summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLauri Eskola2018-08-09 15:49:18 (GMT)
committerLauri Eskola2018-08-09 15:55:58 (GMT)
commit058f3387d788576022c7a67589adce33428b382d (patch)
tree851d87cf73a61029c42761628f6ab7cea8df33ee
parente3458a701a997b21e3005a47d44cadf8a7a1104b (diff)
Issue #2981652 by ApacheEx, corbacho, drpal, dawehner, xjm, alexpott, lauriii: Format core JavaScript using recently add Prettier
(cherry picked from commit e742590eedd0f8bfe0f4f21710df3ddfe0524521)
-rw-r--r--core/.eslintrc.passing.json3
-rw-r--r--core/.prettierignore1
-rw-r--r--core/misc/active-link.es6.js20
-rw-r--r--core/misc/ajax.es6.js404
-rw-r--r--core/misc/ajax.js22
-rw-r--r--core/misc/announce.es6.js8
-rw-r--r--core/misc/autocomplete.es6.js44
-rw-r--r--core/misc/batch.es6.js11
-rw-r--r--core/misc/collapse.es6.js204
-rw-r--r--core/misc/date.es6.js50
-rw-r--r--core/misc/debounce.es6.js6
-rw-r--r--core/misc/details-aria.es6.js23
-rw-r--r--core/misc/dialog/dialog.ajax.es6.js52
-rw-r--r--core/misc/dialog/dialog.es6.js6
-rw-r--r--core/misc/dialog/dialog.jquery-ui.es6.js9
-rw-r--r--core/misc/dialog/dialog.position.es6.js58
-rw-r--r--core/misc/dialog/off-canvas.es6.js101
-rw-r--r--core/misc/displace.es6.js16
-rw-r--r--core/misc/dropbutton/dropbutton.es6.js264
-rw-r--r--core/misc/drupal.es6.js86
-rw-r--r--core/misc/drupal.init.es6.js4
-rw-r--r--core/misc/drupalSettingsLoader.es6.js8
-rw-r--r--core/misc/entity-form.es6.js72
-rw-r--r--core/misc/form.es6.js106
-rw-r--r--core/misc/machine-name.es6.js64
-rw-r--r--core/misc/progress.es6.js225
-rw-r--r--core/misc/states.es6.js141
-rw-r--r--core/misc/states.js18
-rw-r--r--core/misc/tabbingmanager.es6.js506
-rw-r--r--core/misc/tabledrag.es6.js593
-rw-r--r--core/misc/tableheader.es6.js349
-rw-r--r--core/misc/tableresponsive.es6.js224
-rw-r--r--core/misc/tableselect.es6.js153
-rw-r--r--core/misc/timezone.es6.js8
-rw-r--r--core/misc/vertical-tabs.es6.js163
-rw-r--r--core/modules/big_pipe/js/big_pipe.es6.js21
-rw-r--r--core/modules/block/js/block.admin.es6.js49
-rw-r--r--core/modules/block/js/block.es6.js78
-rw-r--r--core/modules/book/book.es6.js28
-rw-r--r--core/modules/ckeditor/js/ckeditor.admin.es6.js228
-rw-r--r--core/modules/ckeditor/js/ckeditor.drupalimage.admin.es6.js23
-rw-r--r--core/modules/ckeditor/js/ckeditor.drupalimage.admin.js5
-rw-r--r--core/modules/ckeditor/js/ckeditor.es6.js117
-rw-r--r--core/modules/ckeditor/js/ckeditor.js4
-rw-r--r--core/modules/ckeditor/js/ckeditor.language.admin.es6.js10
-rw-r--r--core/modules/ckeditor/js/ckeditor.stylescombo.admin.es6.js25
-rw-r--r--core/modules/ckeditor/js/models/Model.es6.js98
-rw-r--r--core/modules/ckeditor/js/plugins/drupalimage/plugin.es6.js98
-rw-r--r--core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js455
-rw-r--r--core/modules/ckeditor/js/plugins/drupallink/plugin.es6.js84
-rw-r--r--core/modules/ckeditor/js/plugins/drupallink/plugin.js16
-rw-r--r--core/modules/ckeditor/js/views/AuralView.es6.js449
-rw-r--r--core/modules/ckeditor/js/views/ControllerView.es6.js705
-rw-r--r--core/modules/ckeditor/js/views/KeyboardView.es6.js525
-rw-r--r--core/modules/ckeditor/js/views/VisualView.es6.js515
-rw-r--r--core/modules/ckeditor/js/views/VisualView.js1
-rw-r--r--core/modules/ckeditor/tests/modules/js/ajax-css.es6.js7
-rw-r--r--core/modules/color/color.es6.js120
-rw-r--r--core/modules/color/preview.es6.js56
-rw-r--r--core/modules/color/tests/modules/color_test/themes/color_test_theme/js/color_test_theme-fontsize.es6.js4
-rw-r--r--core/modules/comment/comment-entity-form.es6.js15
-rw-r--r--core/modules/comment/js/comment-by-viewer.es6.js11
-rw-r--r--core/modules/comment/js/comment-new-indicator.es6.js25
-rw-r--r--core/modules/comment/js/node-new-comments-link.es6.js77
-rw-r--r--core/modules/content_translation/content_translation.admin.es6.js102
-rw-r--r--core/modules/contextual/js/contextual.es6.js69
-rw-r--r--core/modules/contextual/js/contextual.js4
-rw-r--r--core/modules/contextual/js/contextual.toolbar.es6.js34
-rw-r--r--core/modules/contextual/js/models/StateModel.es6.js189
-rw-r--r--core/modules/contextual/js/toolbar/models/StateModel.es6.js193
-rw-r--r--core/modules/contextual/js/toolbar/views/AuralView.es6.js192
-rw-r--r--core/modules/contextual/js/toolbar/views/VisualView.es6.js139
-rw-r--r--core/modules/contextual/js/views/AuralView.es6.js94
-rw-r--r--core/modules/contextual/js/views/KeyboardView.es6.js92
-rw-r--r--core/modules/contextual/js/views/RegionView.es6.js95
-rw-r--r--core/modules/contextual/js/views/VisualView.es6.js145
-rw-r--r--core/modules/editor/js/editor.admin.es6.js234
-rw-r--r--core/modules/editor/js/editor.dialog.es6.js10
-rw-r--r--core/modules/editor/js/editor.es6.js147
-rw-r--r--core/modules/editor/js/editor.formattedTextEditor.es6.js437
-rw-r--r--core/modules/field_ui/field_ui.es6.js145
-rw-r--r--core/modules/file/file.es6.js117
-rw-r--r--core/modules/filter/filter.admin.es6.js91
-rw-r--r--core/modules/filter/filter.es6.js4
-rw-r--r--core/modules/filter/filter.filter_html.admin.es6.js201
-rw-r--r--core/modules/history/js/history.es6.js39
-rw-r--r--core/modules/history/js/mark-as-read.es6.js8
-rw-r--r--core/modules/image/js/editors/image.es6.js654
-rw-r--r--core/modules/image/js/theme.es6.js38
-rw-r--r--core/modules/image/js/theme.js4
-rw-r--r--core/modules/language/language.admin.es6.js23
-rw-r--r--core/modules/layout_builder/js/layout-builder.es6.js82
-rw-r--r--core/modules/locale/locale.admin.es6.js78
-rw-r--r--core/modules/locale/locale.bulk.es6.js26
-rw-r--r--core/modules/locale/locale.datepicker.es6.js135
-rw-r--r--core/modules/media/js/form.es6.js11
-rw-r--r--core/modules/media/js/form.js5
-rw-r--r--core/modules/media/js/type_form.es6.js54
-rw-r--r--core/modules/media_library/js/media_library.click_to_select.es6.js2
-rw-r--r--core/modules/media_library/js/media_library.view.es6.js64
-rw-r--r--core/modules/media_library/js/media_library.view.js4
-rw-r--r--core/modules/media_library/js/media_library.widget.es6.js77
-rw-r--r--core/modules/menu_ui/menu_ui.admin.es6.js27
-rw-r--r--core/modules/menu_ui/menu_ui.es6.js38
-rw-r--r--core/modules/node/content_types.es6.js59
-rw-r--r--core/modules/node/node.es6.js22
-rw-r--r--core/modules/node/node.js5
-rw-r--r--core/modules/node/node.preview.es6.js46
-rw-r--r--core/modules/path/path.es6.js18
-rw-r--r--core/modules/quickedit/js/editors/formEditor.es6.js458
-rw-r--r--core/modules/quickedit/js/editors/plainTextEditor.es6.js266
-rw-r--r--core/modules/quickedit/js/models/AppModel.es6.js69
-rw-r--r--core/modules/quickedit/js/models/AppModel.js1
-rw-r--r--core/modules/quickedit/js/models/BaseModel.es6.js93
-rw-r--r--core/modules/quickedit/js/models/EditorModel.es6.js63
-rw-r--r--core/modules/quickedit/js/models/EditorModel.js1
-rw-r--r--core/modules/quickedit/js/models/EntityModel.es6.js1388
-rw-r--r--core/modules/quickedit/js/models/EntityModel.js4
-rw-r--r--core/modules/quickedit/js/models/FieldModel.es6.js604
-rw-r--r--core/modules/quickedit/js/quickedit.es6.js220
-rw-r--r--core/modules/quickedit/js/quickedit.js9
-rw-r--r--core/modules/quickedit/js/theme.es6.js44
-rw-r--r--core/modules/quickedit/js/util.es6.js43
-rw-r--r--core/modules/quickedit/js/views/AppView.es6.js1145
-rw-r--r--core/modules/quickedit/js/views/AppView.js8
-rw-r--r--core/modules/quickedit/js/views/ContextualLinkView.es6.js132
-rw-r--r--core/modules/quickedit/js/views/EditorView.es6.js571
-rw-r--r--core/modules/quickedit/js/views/EntityDecorationView.es6.js59
-rw-r--r--core/modules/quickedit/js/views/EntityToolbarView.es6.js1013
-rw-r--r--core/modules/quickedit/js/views/FieldDecorationView.es6.js686
-rw-r--r--core/modules/quickedit/js/views/FieldToolbarView.es6.js429
-rw-r--r--core/modules/responsive_image/js/responsive_image.ajax.es6.js4
-rw-r--r--core/modules/settings_tray/js/settings_tray.es6.js144
-rw-r--r--core/modules/simpletest/simpletest.es6.js90
-rw-r--r--core/modules/statistics/statistics.es6.js4
-rw-r--r--core/modules/system/js/system.date.es6.js23
-rw-r--r--core/modules/system/js/system.es6.js22
-rw-r--r--core/modules/system/js/system.modules.es6.js25
-rw-r--r--core/modules/system/js/system.modules.js4
-rw-r--r--core/modules/system/tests/modules/ajax_test/js/insert-ajax.es6.js60
-rw-r--r--core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.es6.js10
-rw-r--r--core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.es6.js8
-rw-r--r--core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.es6.js4
-rw-r--r--core/modules/taxonomy/taxonomy.es6.js26
-rw-r--r--core/modules/text/text.es6.js80
-rw-r--r--core/modules/toolbar/js/escapeAdmin.es6.js16
-rw-r--r--core/modules/toolbar/js/models/MenuModel.es6.js26
-rw-r--r--core/modules/toolbar/js/models/ToolbarModel.es6.js250
-rw-r--r--core/modules/toolbar/js/toolbar.es6.js283
-rw-r--r--core/modules/toolbar/js/toolbar.menu.es6.js40
-rw-r--r--core/modules/toolbar/js/toolbar.menu.js4
-rw-r--r--core/modules/toolbar/js/views/BodyVisualView.es6.js69
-rw-r--r--core/modules/toolbar/js/views/MenuVisualView.es6.js65
-rw-r--r--core/modules/toolbar/js/views/ToolbarAuralView.es6.js134
-rw-r--r--core/modules/toolbar/js/views/ToolbarAuralView.js3
-rw-r--r--core/modules/toolbar/js/views/ToolbarVisualView.es6.js635
-rw-r--r--core/modules/tour/js/tour.es6.js365
-rw-r--r--core/modules/tour/js/tour.js5
-rw-r--r--core/modules/tracker/js/tracker-history.es6.js63
-rw-r--r--core/modules/user/user.es6.js79
-rw-r--r--core/modules/user/user.permissions.es6.js101
-rw-r--r--core/modules/views/js/ajax_view.es6.js71
-rw-r--r--core/modules/views/js/base.es6.js24
-rw-r--r--core/modules/views_ui/js/ajax.es6.js122
-rw-r--r--core/modules/views_ui/js/dialog.views.es6.js27
-rw-r--r--core/modules/views_ui/js/views-admin.es6.js1151
-rw-r--r--core/modules/views_ui/js/views_ui.listing.es6.js21
-rw-r--r--core/profiles/demo_umami/themes/umami/js/components/navigation/menu-main/menu-main.es6.js8
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalCreateRole.js79
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalCreateUser.js62
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalInstall.js32
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalLogin.js13
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalLoginAsAdmin.js12
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalLogout.js5
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalUninstall.js18
-rw-r--r--core/tests/Drupal/Nightwatch/Commands/drupalUserIsLoggedIn.js6
-rw-r--r--core/tests/Drupal/Nightwatch/Tests/exampleTest.js10
-rw-r--r--core/tests/Drupal/Nightwatch/Tests/loginTest.js11
-rw-r--r--core/tests/Drupal/Nightwatch/globals.js37
-rw-r--r--core/tests/Drupal/Nightwatch/nightwatch.conf.js15
-rw-r--r--core/themes/bartik/color/preview.es6.js65
-rw-r--r--core/themes/seven/js/mobile.install.es6.js4
-rw-r--r--core/themes/seven/js/nav-tabs.es6.js11
-rw-r--r--core/themes/seven/js/responsive-details.es6.js15
184 files changed, 13444 insertions, 10447 deletions
diff --git a/core/.eslintrc.passing.json b/core/.eslintrc.passing.json
index 106d05d..5e42232 100644
--- a/core/.eslintrc.passing.json
+++ b/core/.eslintrc.passing.json
@@ -10,7 +10,6 @@
"prefer-destructuring": "off",
"react/no-this-in-sfc": "off",
"react/destructuring-assignment": "off",
- "import/named": "off",
- "prettier/prettier": "off"
+ "import/named": "off"
}
}
diff --git a/core/.prettierignore b/core/.prettierignore
new file mode 100644
index 0000000..2e0da40
--- /dev/null
+++ b/core/.prettierignore
@@ -0,0 +1 @@
+modules/locale/tests/locale_test.es6.js
diff --git a/core/misc/active-link.es6.js b/core/misc/active-link.es6.js
index 425e4f1..fd95376 100644
--- a/core/misc/active-link.es6.js
+++ b/core/misc/active-link.es6.js
@@ -3,7 +3,7 @@
* Attaches behaviors for Drupal's active link marking.
*/
-(function (Drupal, drupalSettings) {
+(function(Drupal, drupalSettings) {
/**
* Append is-active class.
*
@@ -23,8 +23,12 @@
// Start by finding all potentially active links.
const path = drupalSettings.path;
const queryString = JSON.stringify(path.currentQuery);
- const querySelector = path.currentQuery ? `[data-drupal-link-query='${queryString}']` : ':not([data-drupal-link-query])';
- const originalSelectors = [`[data-drupal-link-system-path="${path.currentPath}"]`];
+ const querySelector = path.currentQuery
+ ? `[data-drupal-link-query='${queryString}']`
+ : ':not([data-drupal-link-query])';
+ const originalSelectors = [
+ `[data-drupal-link-system-path="${path.currentPath}"]`,
+ ];
let selectors;
// If this is the front page, we have to check for the <front> path as
@@ -38,7 +42,9 @@
// Links without any hreflang attributes (most of them).
originalSelectors.map(selector => `${selector}:not([hreflang])`),
// Links with hreflang equals to the current language.
- originalSelectors.map(selector => `${selector}[hreflang="${path.currentLanguage}"]`),
+ originalSelectors.map(
+ selector => `${selector}[hreflang="${path.currentLanguage}"]`,
+ ),
);
// Add query string selector for pagers, exposed filters.
@@ -53,7 +59,9 @@
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
- const activeLinks = context.querySelectorAll('[data-drupal-link-system-path].is-active');
+ const activeLinks = context.querySelectorAll(
+ '[data-drupal-link-system-path].is-active',
+ );
const il = activeLinks.length;
for (let i = 0; i < il; i++) {
activeLinks[i].classList.remove('is-active');
@@ -61,4 +69,4 @@
}
},
};
-}(Drupal, drupalSettings));
+})(Drupal, drupalSettings);
diff --git a/core/misc/ajax.es6.js b/core/misc/ajax.es6.js
index fe433f9..440e590 100644
--- a/core/misc/ajax.es6.js
+++ b/core/misc/ajax.es6.js
@@ -11,7 +11,7 @@
* included to provide Ajax capabilities.
*/
-(function ($, window, Drupal, drupalSettings) {
+(function($, window, Drupal, drupalSettings) {
/**
* Attaches the Ajax behavior to each Ajax form element.
*
@@ -32,11 +32,13 @@
if (typeof elementSettings.selector === 'undefined') {
elementSettings.selector = `#${base}`;
}
- $(elementSettings.selector).once('drupal-ajax').each(function () {
- elementSettings.element = this;
- elementSettings.base = base;
- Drupal.ajax(elementSettings);
- });
+ $(elementSettings.selector)
+ .once('drupal-ajax')
+ .each(function() {
+ elementSettings.element = this;
+ elementSettings.base = base;
+ Drupal.ajax(elementSettings);
+ });
}
// Load all Ajax behaviors specified in the settings.
@@ -45,30 +47,32 @@
Drupal.ajax.bindAjaxLinks(document.body);
// This class means to submit the form to the action using Ajax.
- $('.use-ajax-submit').once('ajax').each(function () {
- const elementSettings = {};
-
- // Ajax submits specified in this manner automatically submit to the
- // normal form action.
- elementSettings.url = $(this.form).attr('action');
- // Form submit button clicks need to tell the form what was clicked so
- // it gets passed in the POST request.
- elementSettings.setClick = true;
- // Form buttons use the 'click' event rather than mousedown.
- elementSettings.event = 'click';
- // Clicked form buttons look better with the throbber than the progress
- // bar.
- elementSettings.progress = { type: 'throbber' };
- elementSettings.base = $(this).attr('id');
- elementSettings.element = this;
+ $('.use-ajax-submit')
+ .once('ajax')
+ .each(function() {
+ const elementSettings = {};
+
+ // Ajax submits specified in this manner automatically submit to the
+ // normal form action.
+ elementSettings.url = $(this.form).attr('action');
+ // Form submit button clicks need to tell the form what was clicked so
+ // it gets passed in the POST request.
+ elementSettings.setClick = true;
+ // Form buttons use the 'click' event rather than mousedown.
+ elementSettings.event = 'click';
+ // Clicked form buttons look better with the throbber than the progress
+ // bar.
+ elementSettings.progress = { type: 'throbber' };
+ elementSettings.base = $(this).attr('id');
+ elementSettings.element = this;
- Drupal.ajax(elementSettings);
- });
+ Drupal.ajax(elementSettings);
+ });
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
- Drupal.ajax.expired().forEach((instance) => {
+ Drupal.ajax.expired().forEach(instance => {
// Set this to null and allow garbage collection to reclaim
// the memory.
Drupal.ajax.instances[instance.instanceIndex] = null;
@@ -91,15 +95,19 @@
* @param {string} customMessage
* The custom message.
*/
- Drupal.AjaxError = function (xmlhttp, uri, customMessage) {
+ Drupal.AjaxError = function(xmlhttp, uri, customMessage) {
let statusCode;
let statusText;
let responseText;
if (xmlhttp.status) {
- statusCode = `\n${Drupal.t('An AJAX HTTP error occurred.')}\n${Drupal.t('HTTP Result Code: !status', { '!status': xmlhttp.status })}`;
- }
- else {
- statusCode = `\n${Drupal.t('An AJAX HTTP request terminated abnormally.')}`;
+ statusCode = `\n${Drupal.t('An AJAX HTTP error occurred.')}\n${Drupal.t(
+ 'HTTP Result Code: !status',
+ { '!status': xmlhttp.status },
+ )}`;
+ } else {
+ statusCode = `\n${Drupal.t(
+ 'An AJAX HTTP request terminated abnormally.',
+ )}`;
}
statusCode += `\n${Drupal.t('Debugging information follows.')}`;
const pathText = `\n${Drupal.t('Path: !uri', { '!uri': uri })}`;
@@ -109,9 +117,10 @@
// catch that and the test causes an exception. So we need to catch the
// exception here.
try {
- statusText = `\n${Drupal.t('StatusText: !statusText', { '!statusText': $.trim(xmlhttp.statusText) })}`;
- }
- catch (e) {
+ statusText = `\n${Drupal.t('StatusText: !statusText', {
+ '!statusText': $.trim(xmlhttp.statusText),
+ })}`;
+ } catch (e) {
// Empty.
}
@@ -119,9 +128,10 @@
// Again, we don't have a way to know for sure whether accessing
// xmlhttp.responseText is going to throw an exception. So we'll catch it.
try {
- responseText = `\n${Drupal.t('ResponseText: !responseText', { '!responseText': $.trim(xmlhttp.responseText) })}`;
- }
- catch (e) {
+ responseText = `\n${Drupal.t('ResponseText: !responseText', {
+ '!responseText': $.trim(xmlhttp.responseText),
+ })}`;
+ } catch (e) {
// Empty.
}
@@ -130,16 +140,31 @@
responseText = responseText.replace(/[\n]+\s+/g, '\n');
// We don't need readyState except for status == 0.
- const readyStateText = xmlhttp.status === 0 ? (`\n${Drupal.t('ReadyState: !readyState', { '!readyState': xmlhttp.readyState })}`) : '';
-
- customMessage = customMessage ? (`\n${Drupal.t('CustomMessage: !customMessage', { '!customMessage': customMessage })}`) : '';
+ const readyStateText =
+ xmlhttp.status === 0
+ ? `\n${Drupal.t('ReadyState: !readyState', {
+ '!readyState': xmlhttp.readyState,
+ })}`
+ : '';
+
+ customMessage = customMessage
+ ? `\n${Drupal.t('CustomMessage: !customMessage', {
+ '!customMessage': customMessage,
+ })}`
+ : '';
/**
* Formatted and translated error message.
*
* @type {string}
*/
- this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText;
+ this.message =
+ statusCode +
+ pathText +
+ statusText +
+ customMessage +
+ responseText +
+ readyStateText;
/**
* Used by some browsers to display a more accurate stack trace.
@@ -203,9 +228,11 @@
*
* @see Drupal.AjaxCommands
*/
- Drupal.ajax = function (settings) {
+ Drupal.ajax = function(settings) {
if (arguments.length !== 1) {
- throw new Error('Drupal.ajax() function must be called with one configuration object only');
+ throw new Error(
+ 'Drupal.ajax() function must be called with one configuration object only',
+ );
}
// Map those config keys to variables for the old Drupal.ajax function.
const base = settings.base || false;
@@ -241,8 +268,13 @@
* @return {Array.<Drupal.Ajax>}
* The list of expired {@link Drupal.Ajax} objects.
*/
- Drupal.ajax.expired = function () {
- return Drupal.ajax.instances.filter(instance => instance && instance.element !== false && !document.body.contains(instance.element));
+ Drupal.ajax.expired = function() {
+ return Drupal.ajax.instances.filter(
+ instance =>
+ instance &&
+ instance.element !== false &&
+ !document.body.contains(instance.element),
+ );
};
/**
@@ -251,31 +283,34 @@
* @param {HTMLElement} element
* Element to enable Ajax functionality for.
*/
- Drupal.ajax.bindAjaxLinks = (element) => {
+ Drupal.ajax.bindAjaxLinks = element => {
// Bind Ajax behaviors to all items showing the class.
- $(element).find('.use-ajax').once('ajax').each((i, ajaxLink) => {
- const $linkElement = $(ajaxLink);
-
- const elementSettings = {
- // Clicked links look better with the throbber than the progress bar.
- progress: { type: 'throbber' },
- dialogType: $linkElement.data('dialog-type'),
- dialog: $linkElement.data('dialog-options'),
- dialogRenderer: $linkElement.data('dialog-renderer'),
- base: $linkElement.attr('id'),
- element: ajaxLink,
- };
- const href = $linkElement.attr('href');
- /**
- * For anchor tags, these will go to the target of the anchor rather
- * than the usual location.
- */
- if (href) {
- elementSettings.url = href;
- elementSettings.event = 'click';
- }
- Drupal.ajax(elementSettings);
- });
+ $(element)
+ .find('.use-ajax')
+ .once('ajax')
+ .each((i, ajaxLink) => {
+ const $linkElement = $(ajaxLink);
+
+ const elementSettings = {
+ // Clicked links look better with the throbber than the progress bar.
+ progress: { type: 'throbber' },
+ dialogType: $linkElement.data('dialog-type'),
+ dialog: $linkElement.data('dialog-options'),
+ dialogRenderer: $linkElement.data('dialog-renderer'),
+ base: $linkElement.attr('id'),
+ element: ajaxLink,
+ };
+ const href = $linkElement.attr('href');
+ /**
+ * For anchor tags, these will go to the target of the anchor rather
+ * than the usual location.
+ */
+ if (href) {
+ elementSettings.url = href;
+ elementSettings.event = 'click';
+ }
+ Drupal.ajax(elementSettings);
+ });
};
/**
@@ -338,7 +373,7 @@
* @param {Drupal.Ajax~elementSettings} elementSettings
* Settings for this Ajax object.
*/
- Drupal.Ajax = function (base, element, elementSettings) {
+ Drupal.Ajax = function(base, element, elementSettings) {
const defaults = {
event: element ? 'mousedown' : null,
keypress: true,
@@ -410,8 +445,7 @@
const $element = $(this.element);
if ($element.is('a')) {
this.url = $element.attr('href');
- }
- else if (this.element && element.form) {
+ } else if (this.element && element.form) {
this.url = this.$form.attr('action');
}
}
@@ -505,7 +539,9 @@
// the response headers cannot be accessed for verification.
if (response !== null && !drupalSettings.ajaxTrustedUrl[ajax.url]) {
if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') {
- const customMessage = Drupal.t('The response failed verification so will not be processed.');
+ const customMessage = Drupal.t(
+ 'The response failed verification so will not be processed.',
+ );
return ajax.error(xmlhttprequest, ajax.url, customMessage);
}
}
@@ -530,22 +566,27 @@
// yet available, otherwise append using &.
if (ajax.options.url.indexOf('?') === -1) {
ajax.options.url += '?';
- }
- else {
+ } else {
ajax.options.url += '&';
}
// If this element has a dialog type use if for the wrapper if not use 'ajax'.
- let wrapper = `drupal_${(elementSettings.dialogType || 'ajax')}`;
+ let wrapper = `drupal_${elementSettings.dialogType || 'ajax'}`;
if (elementSettings.dialogRenderer) {
wrapper += `.${elementSettings.dialogRenderer}`;
}
ajax.options.url += `${Drupal.ajax.WRAPPER_FORMAT}=${wrapper}`;
-
// Bind the ajaxSubmit function to the element event.
- $(ajax.element).on(elementSettings.event, function (event) {
- if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) {
- throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', { '!url': ajax.url }));
+ $(ajax.element).on(elementSettings.event, function(event) {
+ if (
+ !drupalSettings.ajaxTrustedUrl[ajax.url] &&
+ !Drupal.url.isLocal(ajax.url)
+ ) {
+ throw new Error(
+ Drupal.t('The callback URL is not local and not trusted: !url', {
+ '!url': ajax.url,
+ }),
+ );
}
return ajax.eventResponse(this, event);
});
@@ -554,7 +595,7 @@
// can be triggered through keyboard input as well as e.g. a mousedown
// action.
if (elementSettings.keypress) {
- $(ajax.element).on('keypress', function (event) {
+ $(ajax.element).on('keypress', function(event) {
return ajax.keypressResponse(this, event);
});
}
@@ -599,7 +640,7 @@
* pre-serialization fails, the Deferred will be returned in the rejected
* state.
*/
- Drupal.Ajax.prototype.execute = function () {
+ Drupal.Ajax.prototype.execute = function() {
// Do not perform another ajax command if one is already in progress.
if (this.ajaxing) {
return;
@@ -609,12 +650,15 @@
this.beforeSerialize(this.element, this.options);
// Return the jqXHR so that external code can hook into the Deferred API.
return $.ajax(this.options);
- }
- catch (e) {
+ } catch (e) {
// Unset the ajax.ajaxing flag here because it won't be unset during
// the complete response.
this.ajaxing = false;
- window.alert(`An error occurred while attempting to process ${this.options.url}: ${e.message}`);
+ window.alert(
+ `An error occurred while attempting to process ${this.options.url}: ${
+ e.message
+ }`,
+ );
// For consistency, return a rejected Deferred (i.e., jqXHR's superclass)
// so that calling code can take appropriate action.
return $.Deferred().reject();
@@ -636,7 +680,7 @@
* @param {jQuery.Event} event
* Triggered event.
*/
- Drupal.Ajax.prototype.keypressResponse = function (element, event) {
+ Drupal.Ajax.prototype.keypressResponse = function(element, event) {
// Create a synonym for this to reduce code confusion.
const ajax = this;
@@ -645,8 +689,14 @@
// where the spacebar activation causes inappropriate activation if
// #ajax['keypress'] is TRUE. On a text-type widget a space should always
// be a space.
- if (event.which === 13 || (event.which === 32 && element.type !== 'text' &&
- element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number')) {
+ if (
+ event.which === 13 ||
+ (event.which === 32 &&
+ element.type !== 'text' &&
+ element.type !== 'textarea' &&
+ element.type !== 'tel' &&
+ element.type !== 'number')
+ ) {
event.preventDefault();
event.stopPropagation();
$(element).trigger(ajax.elementSettings.event);
@@ -666,7 +716,7 @@
* @param {jQuery.Event} event
* Triggered event.
*/
- Drupal.Ajax.prototype.eventResponse = function (element, event) {
+ Drupal.Ajax.prototype.eventResponse = function(element, event) {
event.preventDefault();
event.stopPropagation();
@@ -691,17 +741,19 @@
}
ajax.$form.ajaxSubmit(ajax.options);
- }
- else {
+ } else {
ajax.beforeSerialize(ajax.element, ajax.options);
$.ajax(ajax.options);
}
- }
- catch (e) {
+ } catch (e) {
// Unset the ajax.ajaxing flag here because it won't be unset during
// the complete response.
ajax.ajaxing = false;
- window.alert(`An error occurred while attempting to process ${ajax.options.url}: ${e.message}`);
+ window.alert(
+ `An error occurred while attempting to process ${ajax.options.url}: ${
+ e.message
+ }`,
+ );
}
};
@@ -716,7 +768,7 @@
* @param {object} options
* jQuery.ajax options.
*/
- Drupal.Ajax.prototype.beforeSerialize = function (element, options) {
+ Drupal.Ajax.prototype.beforeSerialize = function(element, options) {
// Allow detaching behaviors to update field values before collecting them.
// This is only needed when field values are added to the POST data, so only
// when there is a form such that this.$form.ajaxSubmit() is used instead of
@@ -751,7 +803,7 @@
* @param {object} options
* jQuery.ajax options.
*/
- Drupal.Ajax.prototype.beforeSubmit = function (formValues, element, options) {
+ Drupal.Ajax.prototype.beforeSubmit = function(formValues, element, options) {
// This function is left empty to make it simple to override for modules
// that wish to add functionality here.
};
@@ -764,7 +816,7 @@
* @param {object} options
* jQuery.ajax options.
*/
- Drupal.Ajax.prototype.beforeSend = function (xmlhttprequest, options) {
+ Drupal.Ajax.prototype.beforeSend = function(xmlhttprequest, options) {
// For forms without file inputs, the jQuery Form plugin serializes the
// form values, and then calls jQuery's $.ajax() function, which invokes
// this handler. In this circumstance, options.extraData is never used. For
@@ -805,8 +857,13 @@
}
// Insert progress indicator.
- const progressIndicatorMethod = `setProgressIndicator${this.progress.type.slice(0, 1).toUpperCase()}${this.progress.type.slice(1).toLowerCase()}`;
- if (progressIndicatorMethod in this && typeof this[progressIndicatorMethod] === 'function') {
+ const progressIndicatorMethod = `setProgressIndicator${this.progress.type
+ .slice(0, 1)
+ .toUpperCase()}${this.progress.type.slice(1).toLowerCase()}`;
+ if (
+ progressIndicatorMethod in this &&
+ typeof this[progressIndicatorMethod] === 'function'
+ ) {
this[progressIndicatorMethod].call(this);
}
};
@@ -819,9 +876,12 @@
* @return {string}
* The HTML markup for the throbber.
*/
- Drupal.theme.ajaxProgressThrobber = (message) => {
+ Drupal.theme.ajaxProgressThrobber = message => {
// Build markup without adding extra white space since it affects rendering.
- const messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : '';
+ const messageMarkup =
+ typeof message === 'string'
+ ? Drupal.theme('ajaxProgressMessage', message)
+ : '';
const throbber = '<div class="throbber">&nbsp;</div>';
return `<div class="ajax-progress ajax-progress-throbber">${throbber}${messageMarkup}</div>`;
@@ -833,7 +893,8 @@
* @return {string}
* The HTML markup for the throbber.
*/
- Drupal.theme.ajaxProgressIndicatorFullscreen = () => '<div class="ajax-progress ajax-progress-fullscreen">&nbsp;</div>';
+ Drupal.theme.ajaxProgressIndicatorFullscreen = () =>
+ '<div class="ajax-progress ajax-progress-fullscreen">&nbsp;</div>';
/**
* Formats text accompanying the AJAX progress throbber.
@@ -843,20 +904,31 @@
* @return {string}
* The HTML markup for the throbber.
*/
- Drupal.theme.ajaxProgressMessage = message => `<div class="message">${message}</div>`;
+ Drupal.theme.ajaxProgressMessage = message =>
+ `<div class="message">${message}</div>`;
/**
* Sets the progress bar progress indicator.
*/
- Drupal.Ajax.prototype.setProgressIndicatorBar = function () {
- const progressBar = new Drupal.ProgressBar(`ajax-progress-${this.element.id}`, $.noop, this.progress.method, $.noop);
+ Drupal.Ajax.prototype.setProgressIndicatorBar = function() {
+ const progressBar = new Drupal.ProgressBar(
+ `ajax-progress-${this.element.id}`,
+ $.noop,
+ this.progress.method,
+ $.noop,
+ );
if (this.progress.message) {
progressBar.setProgress(-1, this.progress.message);
}
if (this.progress.url) {
- progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500);
+ progressBar.startMonitoring(
+ this.progress.url,
+ this.progress.interval || 1500,
+ );
}
- this.progress.element = $(progressBar.element).addClass('ajax-progress ajax-progress-bar');
+ this.progress.element = $(progressBar.element).addClass(
+ 'ajax-progress ajax-progress-bar',
+ );
this.progress.object = progressBar;
$(this.element).after(this.progress.element);
};
@@ -864,15 +936,17 @@
/**
* Sets the throbber progress indicator.
*/
- Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () {
- this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message));
+ Drupal.Ajax.prototype.setProgressIndicatorThrobber = function() {
+ this.progress.element = $(
+ Drupal.theme('ajaxProgressThrobber', this.progress.message),
+ );
$(this.element).after(this.progress.element);
};
/**
* Sets the fullscreen progress indicator.
*/
- Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () {
+ Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function() {
this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen'));
$('body').after(this.progress.element);
};
@@ -885,7 +959,7 @@
* @param {number} status
* XMLHttpRequest status.
*/
- Drupal.Ajax.prototype.success = function (response, status) {
+ Drupal.Ajax.prototype.success = function(response, status) {
// Remove the progress element.
if (this.progress.element) {
$(this.progress.element).remove();
@@ -899,15 +973,21 @@
// we can try to refocus one of its parents. Using addBack reverse the
// result array, meaning that index 0 is the highest parent in the hierarchy
// in this situation it is usually a <form> element.
- const elementParents = $(this.element).parents('[data-drupal-selector]').addBack().toArray();
+ const elementParents = $(this.element)
+ .parents('[data-drupal-selector]')
+ .addBack()
+ .toArray();
// Track if any command is altering the focus so we can avoid changing the
// focus set by the Ajax command.
let focusChanged = false;
- Object.keys(response || {}).forEach((i) => {
+ Object.keys(response || {}).forEach(i => {
if (response[i].command && this.commands[response[i].command]) {
this.commands[response[i].command](this, response[i], status);
- if (response[i].command === 'invoke' && response[i].method === 'focus') {
+ if (
+ response[i].command === 'invoke' &&
+ response[i].method === 'focus'
+ ) {
focusChanged = true;
}
}
@@ -916,11 +996,19 @@
// If the focus hasn't be changed by the ajax commands, try to refocus the
// triggering element or one of its parents if that element does not exist
// anymore.
- if (!focusChanged && this.element && !$(this.element).data('disable-refocus')) {
+ if (
+ !focusChanged &&
+ this.element &&
+ !$(this.element).data('disable-refocus')
+ ) {
let target = false;
for (let n = elementParents.length - 1; !target && n >= 0; n--) {
- target = document.querySelector(`[data-drupal-selector="${elementParents[n].getAttribute('data-drupal-selector')}"]`);
+ target = document.querySelector(
+ `[data-drupal-selector="${elementParents[n].getAttribute(
+ 'data-drupal-selector',
+ )}"]`,
+ );
}
if (target) {
@@ -956,7 +1044,7 @@
* Returns an object with `showEffect`, `hideEffect` and `showSpeed`
* properties.
*/
- Drupal.Ajax.prototype.getEffect = function (response) {
+ Drupal.Ajax.prototype.getEffect = function(response) {
const type = response.effect || this.effect;
const speed = response.speed || this.speed;
@@ -965,13 +1053,11 @@
effect.showEffect = 'show';
effect.hideEffect = 'hide';
effect.showSpeed = '';
- }
- else if (type === 'fade') {
+ } else if (type === 'fade') {
effect.showEffect = 'fadeIn';
effect.hideEffect = 'fadeOut';
effect.showSpeed = speed;
- }
- else {
+ } else {
effect.showEffect = `${type}Toggle`;
effect.hideEffect = `${type}Toggle`;
effect.showSpeed = speed;
@@ -990,7 +1076,7 @@
* @param {string} [customMessage]
* Extra message to print with the Ajax error.
*/
- Drupal.Ajax.prototype.error = function (xmlhttprequest, uri, customMessage) {
+ Drupal.Ajax.prototype.error = function(xmlhttprequest, uri, customMessage) {
// Remove the progress element.
if (this.progress.element) {
$(this.progress.element).remove();
@@ -1031,19 +1117,20 @@
*
* @see https://www.drupal.org/node/2940704
*/
- Drupal.theme.ajaxWrapperNewContent = ($newContent, ajax, response) => (
+ Drupal.theme.ajaxWrapperNewContent = ($newContent, ajax, response) =>
(response.effect || ajax.effect) !== 'none' &&
$newContent.filter(
- i => !(
- // We can not consider HTML comments or whitespace text as separate
+ i =>
+ !// We can not consider HTML comments or whitespace text as separate
// roots, since they do not cause visual regression with effect.
- $newContent[i].nodeName === '#comment' ||
- ($newContent[i].nodeName === '#text' && /^(\s|\n|\r)*$/.test($newContent[i].textContent))
- ),
- ).length > 1 ?
- Drupal.theme('ajaxWrapperMultipleRootElements', $newContent) :
- $newContent
- );
+ (
+ $newContent[i].nodeName === '#comment' ||
+ ($newContent[i].nodeName === '#text' &&
+ /^(\s|\n|\r)*$/.test($newContent[i].textContent))
+ ),
+ ).length > 1
+ ? Drupal.theme('ajaxWrapperMultipleRootElements', $newContent)
+ : $newContent;
/**
* Provide a wrapper for multiple root elements via Ajax.
@@ -1059,9 +1146,8 @@
*
* @see https://www.drupal.org/node/2940704
*/
- Drupal.theme.ajaxWrapperMultipleRootElements = $elements => (
- $('<div></div>').append($elements)
- );
+ Drupal.theme.ajaxWrapperMultipleRootElements = $elements =>
+ $('<div></div>').append($elements);
/**
* @typedef {object} Drupal.AjaxCommands~commandDefinition
@@ -1091,9 +1177,8 @@
*
* @constructor
*/
- Drupal.AjaxCommands = function () {};
+ Drupal.AjaxCommands = function() {};
Drupal.AjaxCommands.prototype = {
-
/**
* Command to insert new content into the DOM.
*
@@ -1113,7 +1198,9 @@
insert(ajax, response) {
// Get information from the response. If it is not there, default to
// our presets.
- const $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper);
+ const $wrapper = response.selector
+ ? $(response.selector)
+ : $(ajax.wrapper);
const method = response.method || ajax.method;
const effect = ajax.getEffect(response);
@@ -1126,7 +1213,12 @@
// behavior will be removed before Drupal 9.0.0. If different behavior is
// needed, the theme functions can be overriden.
// @see https://www.drupal.org/node/2940704
- $newContent = Drupal.theme('ajaxWrapperNewContent', $newContent, ajax, response);
+ $newContent = Drupal.theme(
+ 'ajaxWrapperNewContent',
+ $newContent,
+ ajax,
+ response,
+ );
// If removing content from the wrapper, detach behaviors first.
switch (method) {
@@ -1156,8 +1248,7 @@
$ajaxNewContent.hide();
$newContent.show();
$ajaxNewContent[effect.showEffect](effect.showSpeed);
- }
- else if (effect.showEffect !== 'show') {
+ } else if (effect.showEffect !== 'show') {
$newContent[effect.showEffect](effect.showSpeed);
}
@@ -1190,9 +1281,10 @@
*/
remove(ajax, response, status) {
const settings = response.settings || ajax.settings || drupalSettings;
- $(response.selector).each(function () {
- Drupal.detachBehaviors(this, settings);
- })
+ $(response.selector)
+ .each(function() {
+ Drupal.detachBehaviors(this, settings);
+ })
.remove();
},
@@ -1216,7 +1308,13 @@
if (!$element.hasClass('ajax-changed')) {
$element.addClass('ajax-changed');
if (response.asterisk) {
- $element.find(response.asterisk).append(` <abbr class="ajax-changed" title="${Drupal.t('Changed')}">*</abbr> `);
+ $element
+ .find(response.asterisk)
+ .append(
+ ` <abbr class="ajax-changed" title="${Drupal.t(
+ 'Changed',
+ )}">*</abbr> `,
+ );
}
}
},
@@ -1293,7 +1391,7 @@
// Clean up drupalSettings.ajax.
if (ajaxSettings) {
- Drupal.ajax.expired().forEach((instance) => {
+ Drupal.ajax.expired().forEach(instance => {
// If the Ajax object has been created through drupalSettings.ajax
// it will have a selector. When there is no selector the object
// has been initialized with a special class name picked up by the
@@ -1310,8 +1408,7 @@
if (response.merge) {
$.extend(true, drupalSettings, response.settings);
- }
- else {
+ } else {
ajax.settings = response.settings;
}
},
@@ -1399,7 +1496,9 @@
* The XMLHttpRequest status.
*/
update_build_id(ajax, response, status) {
- $(`input[name="form_build_id"][value="${response.old}"]`).val(response.new);
+ $(`input[name="form_build_id"][value="${response.old}"]`).val(
+ response.new,
+ );
},
/**
@@ -1423,8 +1522,11 @@
$('head').prepend(response.data);
// Add imports in the styles using the addImport method if available.
let match;
- const importMatch = /^@import url\("(.*)"\);$/igm;
- if (document.styleSheets[0].addImport && importMatch.test(response.data)) {
+ const importMatch = /^@import url\("(.*)"\);$/gim;
+ if (
+ document.styleSheets[0].addImport &&
+ importMatch.test(response.data)
+ ) {
importMatch.lastIndex = 0;
do {
match = importMatch.exec(response.data);
@@ -1433,4 +1535,4 @@
}
},
};
-}(jQuery, window, Drupal, drupalSettings));
+})(jQuery, window, Drupal, drupalSettings);
diff --git a/core/misc/ajax.js b/core/misc/ajax.js
index ddec86d..73b4dcc 100644
--- a/core/misc/ajax.js
+++ b/core/misc/ajax.js
@@ -66,21 +66,29 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
statusText = '';
try {
- statusText = '\n' + Drupal.t('StatusText: !statusText', { '!statusText': $.trim(xmlhttp.statusText) });
+ statusText = '\n' + Drupal.t('StatusText: !statusText', {
+ '!statusText': $.trim(xmlhttp.statusText)
+ });
} catch (e) {}
responseText = '';
try {
- responseText = '\n' + Drupal.t('ResponseText: !responseText', { '!responseText': $.trim(xmlhttp.responseText) });
+ responseText = '\n' + Drupal.t('ResponseText: !responseText', {
+ '!responseText': $.trim(xmlhttp.responseText)
+ });
} catch (e) {}
responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, '');
responseText = responseText.replace(/[\n]+\s+/g, '\n');
- var readyStateText = xmlhttp.status === 0 ? '\n' + Drupal.t('ReadyState: !readyState', { '!readyState': xmlhttp.readyState }) : '';
+ var readyStateText = xmlhttp.status === 0 ? '\n' + Drupal.t('ReadyState: !readyState', {
+ '!readyState': xmlhttp.readyState
+ }) : '';
- customMessage = customMessage ? '\n' + Drupal.t('CustomMessage: !customMessage', { '!customMessage': customMessage }) : '';
+ customMessage = customMessage ? '\n' + Drupal.t('CustomMessage: !customMessage', {
+ '!customMessage': customMessage
+ }) : '';
this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText;
@@ -254,7 +262,9 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
$(ajax.element).on(elementSettings.event, function (event) {
if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) {
- throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', { '!url': ajax.url }));
+ throw new Error(Drupal.t('The callback URL is not local and not trusted: !url', {
+ '!url': ajax.url
+ }));
}
return ajax.eventResponse(this, event);
});
@@ -610,7 +620,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
$('head').prepend(response.data);
var match = void 0;
- var importMatch = /^@import url\("(.*)"\);$/igm;
+ var importMatch = /^@import url\("(.*)"\);$/gim;
if (document.styleSheets[0].addImport && importMatch.test(response.data)) {
importMatch.lastIndex = 0;
do {
diff --git a/core/misc/announce.es6.js b/core/misc/announce.es6.js
index 868ac24..f8ab348 100644
--- a/core/misc/announce.es6.js
+++ b/core/misc/announce.es6.js
@@ -18,7 +18,7 @@
* });
*/
-(function (Drupal, debounce) {
+(function(Drupal, debounce) {
let liveElement;
const announcements = [];
@@ -102,7 +102,7 @@
*
* @see http://www.w3.org/WAI/PF/aria-practices/#liveprops
*/
- Drupal.announce = function (text, priority) {
+ Drupal.announce = function(text, priority) {
// Save the text and priority into a closure variable. Multiple simultaneous
// announcements will be concatenated and read in sequence.
announcements.push({
@@ -112,6 +112,6 @@
// Immediately invoke the function that debounce returns. 200 ms is right at
// the cusp where humans notice a pause, so we will wait
// at most this much time before the set of queued announcements is read.
- return (debounce(announce, 200)());
+ return debounce(announce, 200)();
};
-}(Drupal, Drupal.debounce));
+})(Drupal, Drupal.debounce);
diff --git a/core/misc/autocomplete.es6.js b/core/misc/autocomplete.es6.js
index 79ed666..17993cf 100644
--- a/core/misc/autocomplete.es6.js
+++ b/core/misc/autocomplete.es6.js
@@ -3,7 +3,7 @@
* Autocomplete based on jQuery UI.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
let autocomplete;
/**
@@ -30,12 +30,10 @@
if (character === '"') {
current += character;
quote = !quote;
- }
- else if (character === ',' && !quote) {
+ } else if (character === ',' && !quote) {
result.push(current.trim());
current = '';
- }
- else {
+ } else {
current += character;
}
}
@@ -81,7 +79,10 @@
const term = autocomplete.extractLastTerm(event.target.value);
// Abort search if the first character is in firstCharacterBlacklist.
- if (term.length > 0 && options.firstCharacterBlacklist.indexOf(term[0]) !== -1) {
+ if (
+ term.length > 0 &&
+ options.firstCharacterBlacklist.indexOf(term[0]) !== -1
+ ) {
return false;
}
// Only search when the term is at least the minimum length.
@@ -141,9 +142,11 @@
// Check if the term is already cached.
if (autocomplete.cache[elementId].hasOwnProperty(term)) {
showSuggestions(autocomplete.cache[elementId][term]);
- }
- else {
- const options = $.extend({ success: sourceCallbackHandler, data: { q: term } }, autocomplete.ajax);
+ } else {
+ const options = $.extend(
+ { success: sourceCallbackHandler, data: { q: term } },
+ autocomplete.ajax,
+ );
$.ajax(this.element.attr('data-autocomplete-path'), options);
}
}
@@ -211,18 +214,22 @@
Drupal.behaviors.autocomplete = {
attach(context) {
// Act on textfields with the "form-autocomplete" class.
- const $autocomplete = $(context).find('input.form-autocomplete').once('autocomplete');
+ const $autocomplete = $(context)
+ .find('input.form-autocomplete')
+ .once('autocomplete');
if ($autocomplete.length) {
// Allow options to be overriden per instance.
- const blacklist = $autocomplete.attr('data-autocomplete-first-character-blacklist');
+ const blacklist = $autocomplete.attr(
+ 'data-autocomplete-first-character-blacklist',
+ );
$.extend(autocomplete.options, {
- firstCharacterBlacklist: (blacklist) || '',
+ firstCharacterBlacklist: blacklist || '',
});
// Use jQuery UI Autocomplete on the textfield.
- $autocomplete.autocomplete(autocomplete.options)
- .each(function () {
- $(this).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;
- });
+ $autocomplete.autocomplete(autocomplete.options).each(function() {
+ $(this).data('ui-autocomplete')._renderItem =
+ autocomplete.options.renderItem;
+ });
// Use CompositionEvent to handle IME inputs. It requests remote server on "compositionend" event only.
$autocomplete.on('compositionstart.autocomplete', () => {
@@ -235,7 +242,8 @@
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
- $(context).find('input.form-autocomplete')
+ $(context)
+ .find('input.form-autocomplete')
.removeOnce('autocomplete')
.autocomplete('destroy');
}
@@ -277,4 +285,4 @@
};
Drupal.autocomplete = autocomplete;
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/batch.es6.js b/core/misc/batch.es6.js
index 995d1c5..9c8caac 100644
--- a/core/misc/batch.es6.js
+++ b/core/misc/batch.es6.js
@@ -3,7 +3,7 @@
* Drupal's batch API.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Attaches the batch behavior to progress bars.
*
@@ -29,7 +29,12 @@
}
if ($progress.length) {
- progressBar = new Drupal.ProgressBar('updateprogress', updateCallback, 'POST', errorCallback);
+ progressBar = new Drupal.ProgressBar(
+ 'updateprogress',
+ updateCallback,
+ 'POST',
+ errorCallback,
+ );
progressBar.setProgress(-1, batch.initMessage);
progressBar.startMonitoring(`${batch.uri}&op=do`, 10);
// Remove HTML from no-js progress bar.
@@ -39,4 +44,4 @@
}
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/collapse.es6.js b/core/misc/collapse.es6.js
index b97c3e4..52fd244 100644
--- a/core/misc/collapse.es6.js
+++ b/core/misc/collapse.es6.js
@@ -3,7 +3,7 @@
* Polyfill for HTML5 details elements.
*/
-(function ($, Modernizr, Drupal) {
+(function($, Modernizr, Drupal) {
/**
* The collapsible details object represents a single details element.
*
@@ -17,7 +17,10 @@
this.$node.data('details', this);
// Expand details if there are errors inside, or if it contains an
// element that is targeted by the URI fragment identifier.
- const anchor = window.location.hash && window.location.hash !== '#' ? `, ${window.location.hash}` : '';
+ const anchor =
+ window.location.hash && window.location.hash !== '#'
+ ? `, ${window.location.hash}`
+ : '';
if (this.$node.find(`.error${anchor}`).length) {
this.$node.attr('open', true);
}
@@ -27,93 +30,98 @@
this.setupLegend();
}
- $.extend(CollapsibleDetails, /** @lends Drupal.CollapsibleDetails */{
-
- /**
- * Holds references to instantiated CollapsibleDetails objects.
- *
- * @type {Array.<Drupal.CollapsibleDetails>}
- */
- instances: [],
- });
-
- $.extend(CollapsibleDetails.prototype, /** @lends Drupal.CollapsibleDetails# */{
-
- /**
- * Initialize and setup summary events and markup.
- *
- * @fires event:summaryUpdated
- *
- * @listens event:summaryUpdated
- */
- setupSummary() {
- this.$summary = $('<span class="summary"></span>');
- this.$node
- .on('summaryUpdated', $.proxy(this.onSummaryUpdated, this))
- .trigger('summaryUpdated');
- },
-
- /**
- * Initialize and setup legend markup.
- */
- setupLegend() {
- // Turn the summary into a clickable link.
- const $legend = this.$node.find('> summary');
-
- $('<span class="details-summary-prefix visually-hidden"></span>')
- .append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show'))
- .prependTo($legend)
- .after(document.createTextNode(' '));
-
- // .wrapInner() does not retain bound events.
- $('<a class="details-title"></a>')
- .attr('href', `#${this.$node.attr('id')}`)
- .prepend($legend.contents())
- .appendTo($legend);
-
- $legend
- .append(this.$summary)
- .on('click', $.proxy(this.onLegendClick, this));
+ $.extend(
+ CollapsibleDetails,
+ /** @lends Drupal.CollapsibleDetails */ {
+ /**
+ * Holds references to instantiated CollapsibleDetails objects.
+ *
+ * @type {Array.<Drupal.CollapsibleDetails>}
+ */
+ instances: [],
},
-
- /**
- * Handle legend clicks.
- *
- * @param {jQuery.Event} e
- * The event triggered.
- */
- onLegendClick(e) {
- this.toggle();
- e.preventDefault();
- },
-
- /**
- * Update summary.
- */
- onSummaryUpdated() {
- const text = $.trim(this.$node.drupalGetSummary());
- this.$summary.html(text ? ` (${text})` : '');
- },
-
- /**
- * Toggle the visibility of a details element using smooth animations.
- */
- toggle() {
- const isOpen = !!this.$node.attr('open');
- const $summaryPrefix = this.$node.find('> summary span.details-summary-prefix');
- if (isOpen) {
- $summaryPrefix.html(Drupal.t('Show'));
- }
- else {
- $summaryPrefix.html(Drupal.t('Hide'));
- }
- // Delay setting the attribute to emulate chrome behavior and make
- // details-aria.js work as expected with this polyfill.
- setTimeout(() => {
- this.$node.attr('open', !isOpen);
- }, 0);
+ );
+
+ $.extend(
+ CollapsibleDetails.prototype,
+ /** @lends Drupal.CollapsibleDetails# */ {
+ /**
+ * Initialize and setup summary events and markup.
+ *
+ * @fires event:summaryUpdated
+ *
+ * @listens event:summaryUpdated
+ */
+ setupSummary() {
+ this.$summary = $('<span class="summary"></span>');
+ this.$node
+ .on('summaryUpdated', $.proxy(this.onSummaryUpdated, this))
+ .trigger('summaryUpdated');
+ },
+
+ /**
+ * Initialize and setup legend markup.
+ */
+ setupLegend() {
+ // Turn the summary into a clickable link.
+ const $legend = this.$node.find('> summary');
+
+ $('<span class="details-summary-prefix visually-hidden"></span>')
+ .append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show'))
+ .prependTo($legend)
+ .after(document.createTextNode(' '));
+
+ // .wrapInner() does not retain bound events.
+ $('<a class="details-title"></a>')
+ .attr('href', `#${this.$node.attr('id')}`)
+ .prepend($legend.contents())
+ .appendTo($legend);
+
+ $legend
+ .append(this.$summary)
+ .on('click', $.proxy(this.onLegendClick, this));
+ },
+
+ /**
+ * Handle legend clicks.
+ *
+ * @param {jQuery.Event} e
+ * The event triggered.
+ */
+ onLegendClick(e) {
+ this.toggle();
+ e.preventDefault();
+ },
+
+ /**
+ * Update summary.
+ */
+ onSummaryUpdated() {
+ const text = $.trim(this.$node.drupalGetSummary());
+ this.$summary.html(text ? ` (${text})` : '');
+ },
+
+ /**
+ * Toggle the visibility of a details element using smooth animations.
+ */
+ toggle() {
+ const isOpen = !!this.$node.attr('open');
+ const $summaryPrefix = this.$node.find(
+ '> summary span.details-summary-prefix',
+ );
+ if (isOpen) {
+ $summaryPrefix.html(Drupal.t('Show'));
+ } else {
+ $summaryPrefix.html(Drupal.t('Hide'));
+ }
+ // Delay setting the attribute to emulate chrome behavior and make
+ // details-aria.js work as expected with this polyfill.
+ setTimeout(() => {
+ this.$node.attr('open', !isOpen);
+ }, 0);
+ },
},
- });
+ );
/**
* Polyfill HTML5 details element.
@@ -128,10 +136,15 @@
if (Modernizr.details) {
return;
}
- const $collapsibleDetails = $(context).find('details').once('collapse').addClass('collapse-processed');
+ const $collapsibleDetails = $(context)
+ .find('details')
+ .once('collapse')
+ .addClass('collapse-processed');
if ($collapsibleDetails.length) {
for (let i = 0; i < $collapsibleDetails.length; i++) {
- CollapsibleDetails.instances.push(new CollapsibleDetails($collapsibleDetails[i]));
+ CollapsibleDetails.instances.push(
+ new CollapsibleDetails($collapsibleDetails[i]),
+ );
}
}
},
@@ -151,14 +164,21 @@
* The targeted node as a jQuery object.
*/
const handleFragmentLinkClickOrHashChange = (e, $target) => {
- $target.parents('details').not('[open]').find('> summary').trigger('click');
+ $target
+ .parents('details')
+ .not('[open]')
+ .find('> summary')
+ .trigger('click');
};
/**
* Binds a listener to handle fragment link clicks and URL hash changes.
*/
- $('body').on('formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange);
+ $('body').on(
+ 'formFragmentLinkClickOrHashChange.details',
+ handleFragmentLinkClickOrHashChange,
+ );
// Expose constructor in the public space.
Drupal.CollapsibleDetails = CollapsibleDetails;
-}(jQuery, Modernizr, Drupal));
+})(jQuery, Modernizr, Drupal);
diff --git a/core/misc/date.es6.js b/core/misc/date.es6.js
index 1098ce6..94276f1 100644
--- a/core/misc/date.es6.js
+++ b/core/misc/date.es6.js
@@ -3,7 +3,7 @@
* Polyfill for HTML5 date input.
*/
-(function ($, Modernizr, Drupal) {
+(function($, Modernizr, Drupal) {
/**
* Attach datepicker fallback on date elements.
*
@@ -23,30 +23,36 @@
if (Modernizr.inputtypes.date === true) {
return;
}
- $context.find('input[data-drupal-date-format]').once('datePicker').each(function () {
- const $input = $(this);
- const datepickerSettings = {};
- const dateFormat = $input.data('drupalDateFormat');
- // The date format is saved in PHP style, we need to convert to jQuery
- // datepicker.
- datepickerSettings.dateFormat = dateFormat
- .replace('Y', 'yy')
- .replace('m', 'mm')
- .replace('d', 'dd');
- // Add min and max date if set on the input.
- if ($input.attr('min')) {
- datepickerSettings.minDate = $input.attr('min');
- }
- if ($input.attr('max')) {
- datepickerSettings.maxDate = $input.attr('max');
- }
- $input.datepicker(datepickerSettings);
- });
+ $context
+ .find('input[data-drupal-date-format]')
+ .once('datePicker')
+ .each(function() {
+ const $input = $(this);
+ const datepickerSettings = {};
+ const dateFormat = $input.data('drupalDateFormat');
+ // The date format is saved in PHP style, we need to convert to jQuery
+ // datepicker.
+ datepickerSettings.dateFormat = dateFormat
+ .replace('Y', 'yy')
+ .replace('m', 'mm')
+ .replace('d', 'dd');
+ // Add min and max date if set on the input.
+ if ($input.attr('min')) {
+ datepickerSettings.minDate = $input.attr('min');
+ }
+ if ($input.attr('max')) {
+ datepickerSettings.maxDate = $input.attr('max');
+ }
+ $input.datepicker(datepickerSettings);
+ });
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
- $(context).find('input[data-drupal-date-format]').findOnce('datePicker').datepicker('destroy');
+ $(context)
+ .find('input[data-drupal-date-format]')
+ .findOnce('datePicker')
+ .datepicker('destroy');
}
},
};
-}(jQuery, Modernizr, Drupal));
+})(jQuery, Modernizr, Drupal);
diff --git a/core/misc/debounce.es6.js b/core/misc/debounce.es6.js
index e77940b..2defb45 100644
--- a/core/misc/debounce.es6.js
+++ b/core/misc/debounce.es6.js
@@ -26,12 +26,12 @@
* @return {function}
* The debounced function.
*/
-Drupal.debounce = function (func, wait, immediate) {
+Drupal.debounce = function(func, wait, immediate) {
let timeout;
let result;
- return function (...args) {
+ return function(...args) {
const context = this;
- const later = function () {
+ const later = function() {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
diff --git a/core/misc/details-aria.es6.js b/core/misc/details-aria.es6.js
index bf92846..a7c6ca5 100644
--- a/core/misc/details-aria.es6.js
+++ b/core/misc/details-aria.es6.js
@@ -3,7 +3,7 @@
* Add aria attribute handling for details and summary elements.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Handles `aria-expanded` and `aria-pressed` attributes on details elements.
*
@@ -11,15 +11,20 @@
*/
Drupal.behaviors.detailsAria = {
attach() {
- $('body').once('detailsAria').on('click.detailsAria', 'summary', (event) => {
- const $summary = $(event.currentTarget);
- const open = $(event.currentTarget.parentNode).attr('open') === 'open' ? 'false' : 'true';
+ $('body')
+ .once('detailsAria')
+ .on('click.detailsAria', 'summary', event => {
+ const $summary = $(event.currentTarget);
+ const open =
+ $(event.currentTarget.parentNode).attr('open') === 'open'
+ ? 'false'
+ : 'true';
- $summary.attr({
- 'aria-expanded': open,
- 'aria-pressed': open,
+ $summary.attr({
+ 'aria-expanded': open,
+ 'aria-pressed': open,
+ });
});
- });
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/dialog/dialog.ajax.es6.js b/core/misc/dialog/dialog.ajax.es6.js
index a6f2e71..2a017d2 100644
--- a/core/misc/dialog/dialog.ajax.es6.js
+++ b/core/misc/dialog/dialog.ajax.es6.js
@@ -3,7 +3,7 @@
* Extends the Drupal AJAX functionality to integrate the dialog API.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Initialize dialogs for Ajax purposes.
*
@@ -23,7 +23,9 @@
// Add 'ui-front' jQuery UI class so jQuery UI widgets like autocomplete
// sit on top of dialogs. For more information see
// http://api.jqueryui.com/theming/stacking-elements/.
- $('<div id="drupal-modal" class="ui-front"/>').hide().appendTo('body');
+ $('<div id="drupal-modal" class="ui-front"/>')
+ .hide()
+ .appendTo('body');
}
// Special behaviors specific when attaching content within a dialog.
@@ -42,7 +44,7 @@
const originalClose = settings.dialog.close;
// Overwrite the close method to remove the dialog on closing.
- settings.dialog.close = function (event, ...args) {
+ settings.dialog.close = function(event, ...args) {
originalClose.apply(settings.dialog, [event, ...args]);
$(event.target).remove();
};
@@ -59,8 +61,10 @@
*/
prepareDialogButtons($dialog) {
const buttons = [];
- const $buttons = $dialog.find('.form-actions input[type=submit], .form-actions a.button');
- $buttons.each(function () {
+ const $buttons = $dialog.find(
+ '.form-actions input[type=submit], .form-actions a.button',
+ );
+ $buttons.each(function() {
// Hidden form buttons need special attention. For browser consistency,
// the button needs to be "visible" in order to have the enter key fire
// the form submit event. So instead of a simple "hide" or
@@ -82,9 +86,11 @@
// event will not simulate a click. Use the click method instead.
if ($originalButton.is('a')) {
$originalButton[0].click();
- }
- else {
- $originalButton.trigger('mousedown').trigger('mouseup').trigger('click');
+ } else {
+ $originalButton
+ .trigger('mousedown')
+ .trigger('mouseup')
+ .trigger('click');
e.preventDefault();
}
},
@@ -107,14 +113,16 @@
* @return {bool|undefined}
* Returns false if there was no selector property in the response object.
*/
- Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) {
+ Drupal.AjaxCommands.prototype.openDialog = function(ajax, response, status) {
if (!response.selector) {
return false;
}
let $dialog = $(response.selector);
if (!$dialog.length) {
// Create the element if needed.
- $dialog = $(`<div id="${response.selector.replace(/^#/, '')}" class="ui-front"/>`).appendTo('body');
+ $dialog = $(
+ `<div id="${response.selector.replace(/^#/, '')}" class="ui-front"/>`,
+ ).appendTo('body');
}
// Set up the wrapper, if there isn't one.
if (!ajax.wrapper) {
@@ -129,7 +137,9 @@
// Move the buttons to the jQuery UI dialog buttons area.
if (!response.dialogOptions.buttons) {
response.dialogOptions.drupalAutoButtons = true;
- response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog);
+ response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons(
+ $dialog,
+ );
}
// Bind dialogButtonsChange.
@@ -143,13 +153,15 @@
const dialog = Drupal.dialog($dialog.get(0), response.dialogOptions);
if (response.dialogOptions.modal) {
dialog.showModal();
- }
- else {
+ } else {
dialog.show();
}
// Add the standard Drupal class for buttons for style consistency.
- $dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions');
+ $dialog
+ .parent()
+ .find('.ui-dialog-buttonset')
+ .addClass('form-actions');
};
/**
@@ -168,7 +180,7 @@
* @param {number} [status]
* The HTTP status code.
*/
- Drupal.AjaxCommands.prototype.closeDialog = function (ajax, response, status) {
+ Drupal.AjaxCommands.prototype.closeDialog = function(ajax, response, status) {
const $dialog = $(response.selector);
if ($dialog.length) {
Drupal.dialog($dialog.get(0)).close();
@@ -199,7 +211,11 @@
* @param {number} [status]
* The HTTP status code.
*/
- Drupal.AjaxCommands.prototype.setDialogOption = function (ajax, response, status) {
+ Drupal.AjaxCommands.prototype.setDialogOption = function(
+ ajax,
+ response,
+ status,
+ ) {
const $dialog = $(response.selector);
if ($dialog.length) {
$dialog.dialog('option', response.optionName, response.optionValue);
@@ -219,7 +235,7 @@
* Dialog settings.
*/
$(window).on('dialog:aftercreate', (e, dialog, $element, settings) => {
- $element.on('click.dialog', '.dialog-cancel', (e) => {
+ $element.on('click.dialog', '.dialog-cancel', e => {
dialog.close('cancel');
e.preventDefault();
e.stopPropagation();
@@ -239,4 +255,4 @@
$(window).on('dialog:beforeclose', (e, dialog, $element) => {
$element.off('.dialog');
});
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/dialog/dialog.es6.js b/core/misc/dialog/dialog.es6.js
index 26b9107..9b3aaff 100644
--- a/core/misc/dialog/dialog.es6.js
+++ b/core/misc/dialog/dialog.es6.js
@@ -5,7 +5,7 @@
* @see http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#the-dialog-element
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Default dialog options.
*
@@ -59,7 +59,7 @@
* @return {Drupal.dialog~dialogDefinition}
* The dialog instance.
*/
- Drupal.dialog = function (element, options) {
+ Drupal.dialog = function(element, options) {
let undef;
const $element = $(element);
const dialog = {
@@ -94,4 +94,4 @@
return dialog;
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/misc/dialog/dialog.jquery-ui.es6.js b/core/misc/dialog/dialog.jquery-ui.es6.js
index b7023e0..de11405 100644
--- a/core/misc/dialog/dialog.jquery-ui.es6.js
+++ b/core/misc/dialog/dialog.jquery-ui.es6.js
@@ -3,7 +3,7 @@
* Adds default classes to buttons for styling purposes.
*/
-(function ($) {
+(function($) {
$.widget('ui.dialog', $.ui.dialog, {
options: {
buttonClass: 'button',
@@ -15,7 +15,10 @@
let index;
const il = opts.buttons.length;
for (index = 0; index < il; index++) {
- if (opts.buttons[index].primary && opts.buttons[index].primary === true) {
+ if (
+ opts.buttons[index].primary &&
+ opts.buttons[index].primary === true
+ ) {
primaryIndex = index;
delete opts.buttons[index].primary;
break;
@@ -28,4 +31,4 @@
}
},
});
-}(jQuery));
+})(jQuery);
diff --git a/core/misc/dialog/dialog.position.es6.js b/core/misc/dialog/dialog.position.es6.js
index 939fbd8..4c3e915 100644
--- a/core/misc/dialog/dialog.position.es6.js
+++ b/core/misc/dialog/dialog.position.es6.js
@@ -9,9 +9,12 @@
* @event dialogContentResize
*/
-(function ($, Drupal, drupalSettings, debounce, displace) {
+(function($, Drupal, drupalSettings, debounce, displace) {
// autoResize option will turn off resizable and draggable.
- drupalSettings.dialog = $.extend({ autoResize: true, maxHeight: '95%' }, drupalSettings.dialog);
+ drupalSettings.dialog = $.extend(
+ { autoResize: true, maxHeight: '95%' },
+ drupalSettings.dialog,
+ );
/**
* Position the dialog's center at the center of displace.offsets boundaries.
@@ -29,10 +32,14 @@
const left = offsets.left - offsets.right;
const top = offsets.top - offsets.bottom;
- const leftString = `${(left > 0 ? '+' : '-') + Math.abs(Math.round(left / 2))}px`;
- const topString = `${(top > 0 ? '+' : '-') + Math.abs(Math.round(top / 2))}px`;
+ const leftString = `${(left > 0 ? '+' : '-') +
+ Math.abs(Math.round(left / 2))}px`;
+ const topString = `${(top > 0 ? '+' : '-') +
+ Math.abs(Math.round(top / 2))}px`;
options.position = {
- my: `center${left !== 0 ? leftString : ''} center${top !== 0 ? topString : ''}`,
+ my: `center${left !== 0 ? leftString : ''} center${
+ top !== 0 ? topString : ''
+ }`,
of: window,
};
return options;
@@ -54,7 +61,15 @@
* @fires event:dialogContentResize
*/
function resetSize(event) {
- const positionOptions = ['width', 'height', 'minWidth', 'minHeight', 'maxHeight', 'maxWidth', 'position'];
+ const positionOptions = [
+ 'width',
+ 'height',
+ 'minWidth',
+ 'minHeight',
+ 'maxHeight',
+ 'maxWidth',
+ 'position',
+ ];
let adjustedOptions = {};
let windowHeight = $(window).height();
let option;
@@ -65,12 +80,22 @@
optionValue = event.data.settings[option];
if (optionValue) {
// jQuery UI does not support percentages on heights, convert to pixels.
- if (typeof optionValue === 'string' && /%$/.test(optionValue) && /height/i.test(option)) {
+ if (
+ typeof optionValue === 'string' &&
+ /%$/.test(optionValue) &&
+ /height/i.test(option)
+ ) {
// Take offsets in account.
windowHeight -= displace.offsets.top + displace.offsets.bottom;
- adjustedValue = parseInt(0.01 * parseInt(optionValue, 10) * windowHeight, 10);
+ adjustedValue = parseInt(
+ 0.01 * parseInt(optionValue, 10) * windowHeight,
+ 10,
+ );
// Don't force the dialog to be bigger vertically than needed.
- if (option === 'height' && event.data.$element.parent().outerHeight() < adjustedValue) {
+ if (
+ option === 'height' &&
+ event.data.$element.parent().outerHeight() < adjustedValue
+ ) {
adjustedValue = 'auto';
}
adjustedOptions[option] = adjustedValue;
@@ -87,22 +112,27 @@
}
$(window).on({
- 'dialog:aftercreate': function (event, dialog, $element, settings) {
+ 'dialog:aftercreate': function(event, dialog, $element, settings) {
const autoResize = debounce(resetSize, 20);
const eventData = { settings, $element };
if (settings.autoResize === true || settings.autoResize === 'true') {
$element
.dialog('option', { resizable: false, draggable: false })
- .dialog('widget').css('position', 'fixed');
+ .dialog('widget')
+ .css('position', 'fixed');
$(window)
.on('resize.dialogResize scroll.dialogResize', eventData, autoResize)
.trigger('resize.dialogResize');
- $(document).on('drupalViewportOffsetChange.dialogResize', eventData, autoResize);
+ $(document).on(
+ 'drupalViewportOffsetChange.dialogResize',
+ eventData,
+ autoResize,
+ );
}
},
- 'dialog:beforeclose': function (event, dialog, $element) {
+ 'dialog:beforeclose': function(event, dialog, $element) {
$(window).off('.dialogResize');
$(document).off('.dialogResize');
},
});
-}(jQuery, Drupal, drupalSettings, Drupal.debounce, Drupal.displace));
+})(jQuery, Drupal, drupalSettings, Drupal.debounce, Drupal.displace);
diff --git a/core/misc/dialog/off-canvas.es6.js b/core/misc/dialog/off-canvas.es6.js
index a4de606..f8e3fab 100644
--- a/core/misc/dialog/off-canvas.es6.js
+++ b/core/misc/dialog/off-canvas.es6.js
@@ -124,13 +124,27 @@
const eventData = { settings, $element, offCanvasDialog: this };
$element
- .on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.handleDialogResize)
- .on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.bodyPadding);
-
- Drupal.offCanvas.getContainer($element).attr(`data-offset-${Drupal.offCanvas.getEdge()}`, '');
+ .on(
+ 'dialogContentResize.off-canvas',
+ eventData,
+ Drupal.offCanvas.handleDialogResize,
+ )
+ .on(
+ 'dialogContentResize.off-canvas',
+ eventData,
+ Drupal.offCanvas.bodyPadding,
+ );
+
+ Drupal.offCanvas
+ .getContainer($element)
+ .attr(`data-offset-${Drupal.offCanvas.getEdge()}`, '');
$(window)
- .on('resize.off-canvas', eventData, debounce(Drupal.offCanvas.resetSize, 100))
+ .on(
+ 'resize.off-canvas',
+ eventData,
+ debounce(Drupal.offCanvas.resetSize, 100),
+ )
.trigger('resize.off-canvas');
},
@@ -144,7 +158,9 @@
* @return {undefined}
*/
render({ settings }) {
- $('.ui-dialog-off-canvas, .ui-dialog-off-canvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title);
+ $(
+ '.ui-dialog-off-canvas, .ui-dialog-off-canvas .ui-dialog-titlebar',
+ ).toggleClass('ui-dialog-empty-title', !settings.title);
},
/**
@@ -159,7 +175,9 @@
const $element = event.data.$element;
const $container = Drupal.offCanvas.getContainer($element);
- const $offsets = $container.find('> :not(#drupal-off-canvas, .ui-resizable-handle)');
+ const $offsets = $container.find(
+ '> :not(#drupal-off-canvas, .ui-resizable-handle)',
+ );
let offset = 0;
// Let scroll element take all the height available.
@@ -190,9 +208,7 @@
// Only remove the `data-offset-*` attribute if the value previously
// exists and the orientation is changing.
- if (
- Drupal.offCanvas.position &&
- Drupal.offCanvas.position !== position) {
+ if (Drupal.offCanvas.position && Drupal.offCanvas.position !== position) {
container.removeAttr(`data-offset-${Drupal.offCanvas.position}`);
}
// Set a minimum height on $element
@@ -204,7 +220,8 @@
const offsets = displace.offsets;
- const topPosition = position === 'side' && offsets.top !== 0 ? `+${offsets.top}` : '';
+ const topPosition =
+ position === 'side' && offsets.top !== 0 ? `+${offsets.top}` : '';
const adjustedOptions = {
// @see http://api.jqueryui.com/position/
position: {
@@ -214,7 +231,10 @@
},
};
- const height = position === 'side' ? `${$(window).height() - (offsets.top + offsets.bottom)}px` : event.data.settings.height;
+ const height =
+ position === 'side'
+ ? `${$(window).height() - (offsets.top + offsets.bottom)}px`
+ : event.data.settings.height;
container.css({
position: 'fixed',
height,
@@ -237,7 +257,10 @@
*/
bodyPadding(event) {
const position = event.data.settings.drupalOffCanvasPosition;
- if (position === 'side' && $('body').outerWidth() < Drupal.offCanvas.minDisplaceWidth) {
+ if (
+ position === 'side' &&
+ $('body').outerWidth() < Drupal.offCanvas.minDisplaceWidth
+ ) {
return;
}
Drupal.offCanvas.resetPadding();
@@ -246,9 +269,14 @@
const $mainCanvasWrapper = Drupal.offCanvas.$mainCanvasWrapper;
const width = $container.outerWidth();
- const mainCanvasPadding = $mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`);
+ const mainCanvasPadding = $mainCanvasWrapper.css(
+ `padding-${Drupal.offCanvas.getEdge()}`,
+ );
if (position === 'side' && width !== mainCanvasPadding) {
- $mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`, `${width}px`);
+ $mainCanvasWrapper.css(
+ `padding-${Drupal.offCanvas.getEdge()}`,
+ `${width}px`,
+ );
$container.attr(`data-offset-${Drupal.offCanvas.getEdge()}`, width);
displace();
}
@@ -287,7 +315,10 @@
* Resets main canvas wrapper and toolbar padding / margin.
*/
resetPadding() {
- Drupal.offCanvas.$mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`, 0);
+ Drupal.offCanvas.$mainCanvasWrapper.css(
+ `padding-${Drupal.offCanvas.getEdge()}`,
+ 0,
+ );
Drupal.offCanvas.$mainCanvasWrapper.css('padding-top', 0);
displace();
},
@@ -303,24 +334,26 @@
*/
Drupal.behaviors.offCanvasEvents = {
attach: () => {
- $(window).once('off-canvas').on({
- 'dialog:beforecreate': (event, dialog, $element, settings) => {
- if (Drupal.offCanvas.isOffCanvas($element)) {
- Drupal.offCanvas.beforeCreate({ dialog, $element, settings });
- }
- },
- 'dialog:aftercreate': (event, dialog, $element, settings) => {
- if (Drupal.offCanvas.isOffCanvas($element)) {
- Drupal.offCanvas.render({ dialog, $element, settings });
- Drupal.offCanvas.afterCreate({ $element, settings });
- }
- },
- 'dialog:beforeclose': (event, dialog, $element) => {
- if (Drupal.offCanvas.isOffCanvas($element)) {
- Drupal.offCanvas.beforeClose({ dialog, $element });
- }
- },
- });
+ $(window)
+ .once('off-canvas')
+ .on({
+ 'dialog:beforecreate': (event, dialog, $element, settings) => {
+ if (Drupal.offCanvas.isOffCanvas($element)) {
+ Drupal.offCanvas.beforeCreate({ dialog, $element, settings });
+ }
+ },
+ 'dialog:aftercreate': (event, dialog, $element, settings) => {
+ if (Drupal.offCanvas.isOffCanvas($element)) {
+ Drupal.offCanvas.render({ dialog, $element, settings });
+ Drupal.offCanvas.afterCreate({ $element, settings });
+ }
+ },
+ 'dialog:beforeclose': (event, dialog, $element) => {
+ if (Drupal.offCanvas.isOffCanvas($element)) {
+ Drupal.offCanvas.beforeClose({ dialog, $element });
+ }
+ },
+ });
},
};
})(jQuery, Drupal, Drupal.debounce, Drupal.displace);
diff --git a/core/misc/displace.es6.js b/core/misc/displace.es6.js
index 168b5eb..e3909c9 100644
--- a/core/misc/displace.es6.js
+++ b/core/misc/displace.es6.js
@@ -24,7 +24,7 @@
* @event drupalViewportOffsetChange
*/
-(function ($, Drupal, debounce) {
+(function($, Drupal, debounce) {
/**
* @name Drupal.displace.offsets
*
@@ -54,12 +54,15 @@
const $el = $(el);
const documentElement = document.documentElement;
let displacement = 0;
- const horizontal = (edge === 'left' || edge === 'right');
+ const horizontal = edge === 'left' || edge === 'right';
// Get the offset of the element itself.
let placement = $el.offset()[horizontal ? 'left' : 'top'];
// Subtract scroll distance from placement to get the distance
// to the edge of the viewport.
- placement -= window[`scroll${horizontal ? 'X' : 'Y'}`] || document.documentElement[`scroll${horizontal ? 'Left' : 'Top'}`] || 0;
+ placement -=
+ window[`scroll${horizontal ? 'X' : 'Y'}`] ||
+ document.documentElement[`scroll${horizontal ? 'Left' : 'Top'}`] ||
+ 0;
// Find the displacement value according to the edge.
switch (edge) {
// Left and top elements displace as a sum of their own offset value
@@ -109,7 +112,9 @@
*/
function calculateOffset(edge) {
let edgeOffset = 0;
- const displacingElements = document.querySelectorAll(`[data-offset-${edge}]`);
+ const displacingElements = document.querySelectorAll(
+ `[data-offset-${edge}]`,
+ );
const n = displacingElements.length;
for (let i = 0; i < n; i++) {
const el = displacingElements[i];
@@ -202,7 +207,6 @@
*/
Drupal.displace = displace;
$.extend(Drupal.displace, {
-
/**
* Expose offsets to other scripts to avoid having to recalculate offsets.
*
@@ -217,4 +221,4 @@
*/
calculateOffset,
});
-}(jQuery, Drupal, Drupal.debounce));
+})(jQuery, Drupal, Drupal.debounce);
diff --git a/core/misc/dropbutton/dropbutton.es6.js b/core/misc/dropbutton/dropbutton.es6.js
index e654673..54fd3fe 100644
--- a/core/misc/dropbutton/dropbutton.es6.js
+++ b/core/misc/dropbutton/dropbutton.es6.js
@@ -3,7 +3,7 @@
* Dropbutton feature.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* A DropButton presents an HTML list as a button with a primary action.
*
@@ -22,7 +22,10 @@
*/
function DropButton(dropbutton, settings) {
// Merge defaults with settings.
- const options = $.extend({ title: Drupal.t('List additional actions') }, settings);
+ const options = $.extend(
+ { title: Drupal.t('List additional actions') },
+ settings,
+ );
const $dropbutton = $(dropbutton);
/**
@@ -52,38 +55,34 @@
// Add toggle link.
$primary.after(Drupal.theme('dropbuttonToggle', options));
// Bind mouse events.
- this.$dropbutton
- .addClass('dropbutton-multiple')
- .on({
-
- /**
- * Adds a timeout to close the dropdown on mouseleave.
- *
- * @ignore
- */
- 'mouseleave.dropbutton': $.proxy(this.hoverOut, this),
-
- /**
- * Clears timeout when mouseout of the dropdown.
- *
- * @ignore
- */
- 'mouseenter.dropbutton': $.proxy(this.hoverIn, this),
-
- /**
- * Similar to mouseleave/mouseenter, but for keyboard navigation.
- *
- * @ignore
- */
- 'focusout.dropbutton': $.proxy(this.focusOut, this),
-
- /**
- * @ignore
- */
- 'focusin.dropbutton': $.proxy(this.focusIn, this),
- });
- }
- else {
+ this.$dropbutton.addClass('dropbutton-multiple').on({
+ /**
+ * Adds a timeout to close the dropdown on mouseleave.
+ *
+ * @ignore
+ */
+ 'mouseleave.dropbutton': $.proxy(this.hoverOut, this),
+
+ /**
+ * Clears timeout when mouseout of the dropdown.
+ *
+ * @ignore
+ */
+ 'mouseenter.dropbutton': $.proxy(this.hoverIn, this),
+
+ /**
+ * Similar to mouseleave/mouseenter, but for keyboard navigation.
+ *
+ * @ignore
+ */
+ 'focusout.dropbutton': $.proxy(this.focusOut, this),
+
+ /**
+ * @ignore
+ */
+ 'focusin.dropbutton': $.proxy(this.focusIn, this),
+ });
+ } else {
this.$dropbutton.addClass('dropbutton-single');
}
}
@@ -98,7 +97,9 @@
*/
function dropbuttonClickHandler(e) {
e.preventDefault();
- $(e.target).closest('.dropbutton-wrapper').toggleClass('open');
+ $(e.target)
+ .closest('.dropbutton-wrapper')
+ .toggleClass('open');
}
/**
@@ -111,7 +112,9 @@
*/
Drupal.behaviors.dropButton = {
attach(context, settings) {
- const $dropbuttons = $(context).find('.dropbutton-wrapper').once('dropbutton');
+ const $dropbuttons = $(context)
+ .find('.dropbutton-wrapper')
+ .once('dropbutton');
if ($dropbuttons.length) {
// Adds the delegated handler that will toggle dropdowns on click.
const $body = $('body').once('dropbutton-click');
@@ -121,7 +124,9 @@
// Initialize all buttons.
const il = $dropbuttons.length;
for (let i = 0; i < il; i++) {
- DropButton.dropbuttons.push(new DropButton($dropbuttons[i], settings.dropbutton));
+ DropButton.dropbuttons.push(
+ new DropButton($dropbuttons[i], settings.dropbutton),
+ );
}
}
},
@@ -130,100 +135,109 @@
/**
* Extend the DropButton constructor.
*/
- $.extend(DropButton, /** @lends Drupal.DropButton */{
- /**
- * Store all processed DropButtons.
- *
- * @type {Array.<Drupal.DropButton>}
- */
- dropbuttons: [],
- });
+ $.extend(
+ DropButton,
+ /** @lends Drupal.DropButton */ {
+ /**
+ * Store all processed DropButtons.
+ *
+ * @type {Array.<Drupal.DropButton>}
+ */
+ dropbuttons: [],
+ },
+ );
/**
* Extend the DropButton prototype.
*/
- $.extend(DropButton.prototype, /** @lends Drupal.DropButton# */{
-
- /**
- * Toggle the dropbutton open and closed.
- *
- * @param {bool} [show]
- * Force the dropbutton to open by passing true or to close by
- * passing false.
- */
- toggle(show) {
- const isBool = typeof show === 'boolean';
- show = isBool ? show : !this.$dropbutton.hasClass('open');
- this.$dropbutton.toggleClass('open', show);
- },
-
- /**
- * @method
- */
- hoverIn() {
- // Clear any previous timer we were using.
- if (this.timerID) {
- window.clearTimeout(this.timerID);
- }
- },
-
- /**
- * @method
- */
- hoverOut() {
- // Wait half a second before closing.
- this.timerID = window.setTimeout($.proxy(this, 'close'), 500);
- },
-
- /**
- * @method
- */
- open() {
- this.toggle(true);
- },
-
- /**
- * @method
- */
- close() {
- this.toggle(false);
- },
-
- /**
- * @param {jQuery.Event} e
- * The event triggered.
- */
- focusOut(e) {
- this.hoverOut.call(this, e);
- },
-
- /**
- * @param {jQuery.Event} e
- * The event triggered.
- */
- focusIn(e) {
- this.hoverIn.call(this, e);
+ $.extend(
+ DropButton.prototype,
+ /** @lends Drupal.DropButton# */ {
+ /**
+ * Toggle the dropbutton open and closed.
+ *
+ * @param {bool} [show]
+ * Force the dropbutton to open by passing true or to close by
+ * passing false.
+ */
+ toggle(show) {
+ const isBool = typeof show === 'boolean';
+ show = isBool ? show : !this.$dropbutton.hasClass('open');
+ this.$dropbutton.toggleClass('open', show);
+ },
+
+ /**
+ * @method
+ */
+ hoverIn() {
+ // Clear any previous timer we were using.
+ if (this.timerID) {
+ window.clearTimeout(this.timerID);
+ }
+ },
+
+ /**
+ * @method
+ */
+ hoverOut() {
+ // Wait half a second before closing.
+ this.timerID = window.setTimeout($.proxy(this, 'close'), 500);
+ },
+
+ /**
+ * @method
+ */
+ open() {
+ this.toggle(true);
+ },
+
+ /**
+ * @method
+ */
+ close() {
+ this.toggle(false);
+ },
+
+ /**
+ * @param {jQuery.Event} e
+ * The event triggered.
+ */
+ focusOut(e) {
+ this.hoverOut.call(this, e);
+ },
+
+ /**
+ * @param {jQuery.Event} e
+ * The event triggered.
+ */
+ focusIn(e) {
+ this.hoverIn.call(this, e);
+ },
},
- });
-
- $.extend(Drupal.theme, /** @lends Drupal.theme */{
-
- /**
- * A toggle is an interactive element often bound to a click handler.
- *
- * @param {object} options
- * Options object.
- * @param {string} [options.title]
- * The button text.
- *
- * @return {string}
- * A string representing a DOM fragment.
- */
- dropbuttonToggle(options) {
- return `<li class="dropbutton-toggle"><button type="button"><span class="dropbutton-arrow"><span class="visually-hidden">${options.title}</span></span></button></li>`;
+ );
+
+ $.extend(
+ Drupal.theme,
+ /** @lends Drupal.theme */ {
+ /**
+ * A toggle is an interactive element often bound to a click handler.
+ *
+ * @param {object} options
+ * Options object.
+ * @param {string} [options.title]
+ * The button text.
+ *
+ * @return {string}
+ * A string representing a DOM fragment.
+ */
+ dropbuttonToggle(options) {
+ return `<li class="dropbutton-toggle"><button type="button"><span class="dropbutton-arrow"><span class="visually-hidden">${
+ options.title
+ }</span></span></button></li>`;
+ },
},
- });
+ );
// Expose constructor in the public space.
Drupal.DropButton = DropButton;
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/drupal.es6.js b/core/misc/drupal.es6.js
index 260a7d7..ea47bb7 100644
--- a/core/misc/drupal.es6.js
+++ b/core/misc/drupal.es6.js
@@ -42,7 +42,7 @@ window.Drupal = { behaviors: {}, locale: {} };
// JavaScript should be made compatible with libraries other than jQuery by
// wrapping it in an anonymous closure.
-(function (Drupal, drupalSettings, drupalTranslations) {
+(function(Drupal, drupalSettings, drupalTranslations) {
/**
* Helper to rethrow errors asynchronously.
*
@@ -52,7 +52,7 @@ window.Drupal = { behaviors: {}, locale: {} };
* @param {Error|string} error
* The error to be thrown.
*/
- Drupal.throwError = function (error) {
+ Drupal.throwError = function(error) {
setTimeout(() => {
throw error;
}, 0);
@@ -147,18 +147,17 @@ window.Drupal = { behaviors: {}, locale: {} };
*
* @throws {Drupal~DrupalBehaviorError}
*/
- Drupal.attachBehaviors = function (context, settings) {
+ Drupal.attachBehaviors = function(context, settings) {
context = context || document;
settings = settings || drupalSettings;
const behaviors = Drupal.behaviors;
// Execute all of them.
- Object.keys(behaviors || {}).forEach((i) => {
+ Object.keys(behaviors || {}).forEach(i => {
if (typeof behaviors[i].attach === 'function') {
// Don't stop the execution of behaviors in case of an error.
try {
behaviors[i].attach(context, settings);
- }
- catch (e) {
+ } catch (e) {
Drupal.throwError(e);
}
}
@@ -206,19 +205,18 @@ window.Drupal = { behaviors: {}, locale: {} };
* @see Drupal~behaviorDetach
* @see Drupal.attachBehaviors
*/
- Drupal.detachBehaviors = function (context, settings, trigger) {
+ Drupal.detachBehaviors = function(context, settings, trigger) {
context = context || document;
settings = settings || drupalSettings;
trigger = trigger || 'unload';
const behaviors = Drupal.behaviors;
// Execute all of them.
- Object.keys(behaviors || {}).forEach((i) => {
+ Object.keys(behaviors || {}).forEach(i => {
if (typeof behaviors[i].detach === 'function') {
// Don't stop the execution of behaviors in case of an error.
try {
behaviors[i].detach(context, settings, trigger);
- }
- catch (e) {
+ } catch (e) {
Drupal.throwError(e);
}
}
@@ -236,8 +234,9 @@ window.Drupal = { behaviors: {}, locale: {} };
*
* @ingroup sanitization
*/
- Drupal.checkPlain = function (str) {
- str = str.toString()
+ Drupal.checkPlain = function(str) {
+ str = str
+ .toString()
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
@@ -266,11 +265,11 @@ window.Drupal = { behaviors: {}, locale: {} };
*
* @see Drupal.t
*/
- Drupal.formatString = function (str, args) {
+ Drupal.formatString = function(str, args) {
// Keep args intact.
const processedArgs = {};
// Transform arguments before inserting them.
- Object.keys(args || {}).forEach((key) => {
+ Object.keys(args || {}).forEach(key => {
switch (key.charAt(0)) {
// Escaped only.
case '@':
@@ -308,7 +307,7 @@ window.Drupal = { behaviors: {}, locale: {} };
* @return {string}
* The replaced string.
*/
- Drupal.stringReplace = function (str, args, keys) {
+ Drupal.stringReplace = function(str, args, keys) {
if (str.length === 0) {
return str;
}
@@ -359,12 +358,17 @@ window.Drupal = { behaviors: {}, locale: {} };
* The formatted string.
* The translated string.
*/
- Drupal.t = function (str, args, options) {
+ Drupal.t = function(str, args, options) {
options = options || {};
options.context = options.context || '';
// Fetch the localized version of the string.
- if (typeof drupalTranslations !== 'undefined' && drupalTranslations.strings && drupalTranslations.strings[options.context] && drupalTranslations.strings[options.context][str]) {
+ if (
+ typeof drupalTranslations !== 'undefined' &&
+ drupalTranslations.strings &&
+ drupalTranslations.strings[options.context] &&
+ drupalTranslations.strings[options.context][str]
+ ) {
str = drupalTranslations.strings[options.context][str];
}
@@ -383,7 +387,7 @@ window.Drupal = { behaviors: {}, locale: {} };
* @return {string}
* The full URL.
*/
- Drupal.url = function (path) {
+ Drupal.url = function(path) {
return drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + path;
};
@@ -400,15 +404,14 @@ window.Drupal = { behaviors: {}, locale: {} };
* @see https://grack.com/blog/2009/11/17/absolutizing-url-in-javascript
* @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L53
*/
- Drupal.url.toAbsolute = function (url) {
+ Drupal.url.toAbsolute = function(url) {
const urlParsingNode = document.createElement('a');
// Decode the URL first; this is required by IE <= 6. Decoding non-UTF-8
// strings may throw an exception.
try {
url = decodeURIComponent(url);
- }
- catch (e) {
+ } catch (e) {
// Empty.
}
@@ -430,7 +433,7 @@ window.Drupal = { behaviors: {}, locale: {} };
*
* @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58
*/
- Drupal.url.isLocal = function (url) {
+ Drupal.url.isLocal = function(url) {
// Always use browser-derived absolute URLs in the comparison, to avoid
// attempts to break out of the base path using directory traversal.
let absoluteUrl = Drupal.url.toAbsolute(url);
@@ -441,19 +444,19 @@ window.Drupal = { behaviors: {}, locale: {} };
if (protocol === 'http:' && absoluteUrl.indexOf('https:') === 0) {
protocol = 'https:';
}
- let baseUrl = `${protocol}//${window.location.host}${drupalSettings.path.baseUrl.slice(0, -1)}`;
+ let baseUrl = `${protocol}//${
+ window.location.host
+ }${drupalSettings.path.baseUrl.slice(0, -1)}`;
// Decoding non-UTF-8 strings may throw an exception.
try {
absoluteUrl = decodeURIComponent(absoluteUrl);
- }
- catch (e) {
+ } catch (e) {
// Empty.
}
try {
baseUrl = decodeURIComponent(baseUrl);
- }
- catch (e) {
+ } catch (e) {
// Empty.
}
@@ -495,19 +498,28 @@ window.Drupal = { behaviors: {}, locale: {} };
* @return {string}
* A translated string.
*/
- Drupal.formatPlural = function (count, singular, plural, args, options) {
+ Drupal.formatPlural = function(count, singular, plural, args, options) {
args = args || {};
args['@count'] = count;
const pluralDelimiter = drupalSettings.pluralDelimiter;
- const translations = Drupal.t(singular + pluralDelimiter + plural, args, options).split(pluralDelimiter);
+ const translations = Drupal.t(
+ singular + pluralDelimiter + plural,
+ args,
+ options,
+ ).split(pluralDelimiter);
let index = 0;
// Determine the index of the plural form.
- if (typeof drupalTranslations !== 'undefined' && drupalTranslations.pluralFormula) {
- index = count in drupalTranslations.pluralFormula ? drupalTranslations.pluralFormula[count] : drupalTranslations.pluralFormula.default;
- }
- else if (args['@count'] !== 1) {
+ if (
+ typeof drupalTranslations !== 'undefined' &&
+ drupalTranslations.pluralFormula
+ ) {
+ index =
+ count in drupalTranslations.pluralFormula
+ ? drupalTranslations.pluralFormula[count]
+ : drupalTranslations.pluralFormula.default;
+ } else if (args['@count'] !== 1) {
index = 1;
}
@@ -525,7 +537,7 @@ window.Drupal = { behaviors: {}, locale: {} };
* @return {string}
* The encoded path.
*/
- Drupal.encodePath = function (item) {
+ Drupal.encodePath = function(item) {
return window.encodeURIComponent(item).replace(/%2F/g, '/');
};
@@ -553,7 +565,7 @@ window.Drupal = { behaviors: {}, locale: {} };
* Any data the theme function returns. This could be a plain HTML string,
* but also a complex object.
*/
- Drupal.theme = function (func, ...args) {
+ Drupal.theme = function(func, ...args) {
if (func in Drupal.theme) {
return Drupal.theme[func](...args);
}
@@ -568,7 +580,7 @@ window.Drupal = { behaviors: {}, locale: {} };
* @return {string}
* The formatted text (html).
*/
- Drupal.theme.placeholder = function (str) {
+ Drupal.theme.placeholder = function(str) {
return `<em class="placeholder">${Drupal.checkPlain(str)}</em>`;
};
-}(Drupal, window.drupalSettings, window.drupalTranslations));
+})(Drupal, window.drupalSettings, window.drupalTranslations);
diff --git a/core/misc/drupal.init.es6.js b/core/misc/drupal.init.es6.js
index 62cd029..d5050f1 100644
--- a/core/misc/drupal.init.es6.js
+++ b/core/misc/drupal.init.es6.js
@@ -9,9 +9,9 @@ document.documentElement.className += ' js';
// JavaScript should be made compatible with libraries other than jQuery by
// wrapping it in an anonymous closure.
-(function (domready, Drupal, drupalSettings) {
+(function(domready, Drupal, drupalSettings) {
// Attach all behaviors.
domready(() => {
Drupal.attachBehaviors(document, drupalSettings);
});
-}(domready, Drupal, window.drupalSettings));
+})(domready, Drupal, window.drupalSettings);
diff --git a/core/misc/drupalSettingsLoader.es6.js b/core/misc/drupalSettingsLoader.es6.js
index 2e58071..63494d9 100644
--- a/core/misc/drupalSettingsLoader.es6.js
+++ b/core/misc/drupalSettingsLoader.es6.js
@@ -3,9 +3,11 @@
* Parse inline JSON and initialize the drupalSettings global object.
*/
-(function () {
+(function() {
// Use direct child elements to harden against XSS exploits when CSP is on.
- const settingsElement = document.querySelector('head > script[type="application/json"][data-drupal-selector="drupal-settings-json"], body > script[type="application/json"][data-drupal-selector="drupal-settings-json"]');
+ const settingsElement = document.querySelector(
+ 'head > script[type="application/json"][data-drupal-selector="drupal-settings-json"], body > script[type="application/json"][data-drupal-selector="drupal-settings-json"]',
+ );
/**
* Variable generated by Drupal with all the configuration created from PHP.
@@ -19,4 +21,4 @@
if (settingsElement !== null) {
window.drupalSettings = JSON.parse(settingsElement.textContent);
}
-}());
+})();
diff --git a/core/misc/entity-form.es6.js b/core/misc/entity-form.es6.js
index a043301..a9a10c2 100644
--- a/core/misc/entity-form.es6.js
+++ b/core/misc/entity-form.es6.js
@@ -3,7 +3,7 @@
* Defines Javascript behaviors for the block_content module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Sets summaries about revision and translation of entities.
*
@@ -18,36 +18,54 @@
Drupal.behaviors.entityContentDetailsSummaries = {
attach(context) {
const $context = $(context);
- $context.find('.entity-content-form-revision-information').drupalSetSummary((context) => {
- const $revisionContext = $(context);
- const revisionCheckbox = $revisionContext.find('.js-form-item-revision input');
+ $context
+ .find('.entity-content-form-revision-information')
+ .drupalSetSummary(context => {
+ const $revisionContext = $(context);
+ const revisionCheckbox = $revisionContext.find(
+ '.js-form-item-revision input',
+ );
- // Return 'New revision' if the 'Create new revision' checkbox is checked,
- // or if the checkbox doesn't exist, but the revision log does. For users
- // without the "Administer content" permission the checkbox won't appear,
- // but the revision log will if the content type is set to auto-revision.
- if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $revisionContext.find('.js-form-item-revision-log textarea').length)) {
- return Drupal.t('New revision');
- }
+ // Return 'New revision' if the 'Create new revision' checkbox is checked,
+ // or if the checkbox doesn't exist, but the revision log does. For users
+ // without the "Administer content" permission the checkbox won't appear,
+ // but the revision log will if the content type is set to auto-revision.
+ if (
+ revisionCheckbox.is(':checked') ||
+ (!revisionCheckbox.length &&
+ $revisionContext.find('.js-form-item-revision-log textarea')
+ .length)
+ ) {
+ return Drupal.t('New revision');
+ }
- return Drupal.t('No revision');
- });
+ return Drupal.t('No revision');
+ });
- $context.find('details.entity-translation-options').drupalSetSummary((context) => {
- const $translationContext = $(context);
- let translate;
- let $checkbox = $translationContext.find('.js-form-item-translation-translate input');
+ $context
+ .find('details.entity-translation-options')
+ .drupalSetSummary(context => {
+ const $translationContext = $(context);
+ let translate;
+ let $checkbox = $translationContext.find(
+ '.js-form-item-translation-translate input',
+ );
- if ($checkbox.length) {
- translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated');
- }
- else {
- $checkbox = $translationContext.find('.js-form-item-translation-retranslate input');
- translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated');
- }
+ if ($checkbox.length) {
+ translate = $checkbox.is(':checked')
+ ? Drupal.t('Needs to be updated')
+ : Drupal.t('Does not need to be updated');
+ } else {
+ $checkbox = $translationContext.find(
+ '.js-form-item-translation-retranslate input',
+ );
+ translate = $checkbox.is(':checked')
+ ? Drupal.t('Flag other translations as outdated')
+ : Drupal.t('Do not flag other translations as outdated');
+ }
- return translate;
- });
+ return translate;
+ });
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/form.es6.js b/core/misc/form.es6.js
index ac59039..06a53b2 100644
--- a/core/misc/form.es6.js
+++ b/core/misc/form.es6.js
@@ -22,16 +22,16 @@
* @event formFragmentLinkClickOrHashChange
*/
-(function ($, Drupal, debounce) {
+(function($, Drupal, debounce) {
/**
* Retrieves the summary for the first element.
*
* @return {string}
* The text of the summary.
*/
- $.fn.drupalGetSummary = function () {
+ $.fn.drupalGetSummary = function() {
const callback = this.data('summaryCallback');
- return (this[0] && callback) ? $.trim(callback(this[0])) : '';
+ return this[0] && callback ? $.trim(callback(this[0])) : '';
};
/**
@@ -48,29 +48,30 @@
*
* @listens event:formUpdated
*/
- $.fn.drupalSetSummary = function (callback) {
+ $.fn.drupalSetSummary = function(callback) {
const self = this;
// To facilitate things, the callback should always be a function. If it's
// not, we wrap it into an anonymous function which just returns the value.
if (typeof callback !== 'function') {
const val = callback;
- callback = function () {
+ callback = function() {
return val;
};
}
- return this
- .data('summaryCallback', callback)
- // To prevent duplicate events, the handlers are first removed and then
- // (re-)added.
- .off('formUpdated.summary')
- .on('formUpdated.summary', () => {
- self.trigger('summaryUpdated');
- })
- // The actual summaryUpdated handler doesn't fire when the callback is
- // changed, so we have to do this manually.
- .trigger('summaryUpdated');
+ return (
+ this.data('summaryCallback', callback)
+ // To prevent duplicate events, the handlers are first removed and then
+ // (re-)added.
+ .off('formUpdated.summary')
+ .on('formUpdated.summary', () => {
+ self.trigger('summaryUpdated');
+ })
+ // The actual summaryUpdated handler doesn't fire when the callback is
+ // changed, so we have to do this manually.
+ .trigger('summaryUpdated')
+ );
};
/**
@@ -121,13 +122,13 @@
const previousValues = $form.attr('data-drupal-form-submit-last');
if (previousValues === formValues) {
e.preventDefault();
- }
- else {
+ } else {
$form.attr('data-drupal-form-submit-last', formValues);
}
}
- $('body').once('form-single-submit')
+ $('body')
+ .once('form-single-submit')
.on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit);
},
};
@@ -154,11 +155,13 @@
* Array of IDs for form fields.
*/
function fieldsList(form) {
- const $fieldList = $(form).find('[name]').map(
- // We use id to avoid name duplicates on radio fields and filter out
- // elements with a name but no id.
- (index, element) => element.getAttribute('id'),
- );
+ const $fieldList = $(form)
+ .find('[name]')
+ .map(
+ // We use id to avoid name duplicates on radio fields and filter out
+ // elements with a name but no id.
+ (index, element) => element.getAttribute('id'),
+ );
// Return a true array.
return $.makeArray($fieldList);
}
@@ -179,16 +182,18 @@
attach(context) {
const $context = $(context);
const contextIsForm = $context.is('form');
- const $forms = (contextIsForm ? $context : $context.find('form')).once('form-updated');
+ const $forms = (contextIsForm ? $context : $context.find('form')).once(
+ 'form-updated',
+ );
let formFields;
if ($forms.length) {
// Initialize form behaviors, use $.makeArray to be able to use native
// forEach array method and have the callback parameters in the right
// order.
- $.makeArray($forms).forEach((form) => {
+ $.makeArray($forms).forEach(form => {
const events = 'change.formUpdated input.formUpdated ';
- const eventHandler = debounce((event) => {
+ const eventHandler = debounce(event => {
triggerFormUpdated(event.target);
}, 300);
formFields = fieldsList(form).join(',');
@@ -213,9 +218,12 @@
const $context = $(context);
const contextIsForm = $context.is('form');
if (trigger === 'unload') {
- const $forms = (contextIsForm ? $context : $context.find('form')).removeOnce('form-updated');
+ const $forms = (contextIsForm
+ ? $context
+ : $context.find('form')
+ ).removeOnce('form-updated');
if ($forms.length) {
- $.makeArray($forms).forEach((form) => {
+ $.makeArray($forms).forEach(form => {
form.removeAttribute('data-drupal-form-fields');
$(form).off('.formUpdated');
});
@@ -235,19 +243,23 @@
Drupal.behaviors.fillUserInfoFromBrowser = {
attach(context, settings) {
const userInfo = ['name', 'mail', 'homepage'];
- const $forms = $('[data-user-info-from-browser]').once('user-info-from-browser');
+ const $forms = $('[data-user-info-from-browser]').once(
+ 'user-info-from-browser',
+ );
if ($forms.length) {
- userInfo.forEach((info) => {
+ userInfo.forEach(info => {
const $element = $forms.find(`[name=${info}]`);
const browserData = localStorage.getItem(`Drupal.visitor.${info}`);
- const emptyOrDefault = ($element.val() === '' || ($element.attr('data-drupal-default-value') === $element.val()));
+ const emptyOrDefault =
+ $element.val() === '' ||
+ $element.attr('data-drupal-default-value') === $element.val();
if ($element.length && emptyOrDefault && browserData) {
$element.val(browserData);
}
});
}
$forms.on('submit', () => {
- userInfo.forEach((info) => {
+ userInfo.forEach(info => {
const $element = $forms.find(`[name=${info}]`);
if ($element.length) {
localStorage.setItem(`Drupal.visitor.${info}`, $element.val());
@@ -265,12 +277,13 @@
*
* @fires event:formFragmentLinkClickOrHashChange
*/
- const handleFragmentLinkClickOrHashChange = (e) => {
+ const handleFragmentLinkClickOrHashChange = e => {
let url;
if (e.type === 'click') {
- url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget;
- }
- else {
+ url = e.currentTarget.location
+ ? e.currentTarget.location
+ : e.currentTarget;
+ } else {
url = window.location;
}
const hash = url.hash.substr(1);
@@ -286,10 +299,17 @@
}
};
- const debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true);
+ const debouncedHandleFragmentLinkClickOrHashChange = debounce(
+ handleFragmentLinkClickOrHashChange,
+ 300,
+ true,
+ );
// Binds a listener to handle URL fragment changes.
- $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange);
+ $(window).on(
+ 'hashchange.form-fragment',
+ debouncedHandleFragmentLinkClickOrHashChange,
+ );
/**
* Binds a listener to handle clicks on fragment links and absolute URL links
@@ -297,5 +317,9 @@
* because clicking such links doesn't trigger a hash change when the fragment
* is already in the URL.
*/
- $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange);
-}(jQuery, Drupal, Drupal.debounce));
+ $(document).on(
+ 'click.form-fragment',
+ 'a[href*="#"]',
+ debouncedHandleFragmentLinkClickOrHashChange,
+ );
+})(jQuery, Drupal, Drupal.debounce);
diff --git a/core/misc/machine-name.es6.js b/core/misc/machine-name.es6.js
index ee7f528..0fee7f6 100644
--- a/core/misc/machine-name.es6.js
+++ b/core/misc/machine-name.es6.js
@@ -3,7 +3,7 @@
* Machine name functionality.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Attach the machine-readable name form element behavior.
*
@@ -13,7 +13,6 @@
* Attaches machine-name behaviors.
*/
Drupal.behaviors.machineName = {
-
/**
* Attaches the behavior.
*
@@ -59,7 +58,10 @@
const baseValue = $(e.target).val();
const rx = new RegExp(options.replace_pattern, 'g');
- const expected = baseValue.toLowerCase().replace(rx, options.replace).substr(0, options.maxlength);
+ const 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.
@@ -76,26 +78,35 @@
}
if (baseValue.toLowerCase() !== expected) {
timeout = setTimeout(() => {
- xhr = self.transliterate(baseValue, options).done((machine) => {
+ xhr = self.transliterate(baseValue, options).done(machine => {
self.showMachineName(machine.substr(0, options.maxlength), data);
});
}, 300);
- }
- else {
+ } else {
self.showMachineName(expected, data);
}
}
- Object.keys(settings.machineName).forEach((sourceId) => {
+ Object.keys(settings.machineName).forEach(sourceId => {
let machine = '';
const options = settings.machineName[sourceId];
- const $source = $context.find(sourceId).addClass('machine-name-source').once('machine-name');
- const $target = $context.find(options.target).addClass('machine-name-target');
+ const $source = $context
+ .find(sourceId)
+ .addClass('machine-name-source')
+ .once('machine-name');
+ const $target = $context
+ .find(options.target)
+ .addClass('machine-name-target');
const $suffix = $context.find(options.suffix);
const $wrapper = $target.closest('.js-form-item');
// All elements have to exist.
- if (!$source.length || !$target.length || !$suffix.length || !$wrapper.length) {
+ if (
+ !$source.length ||
+ !$target.length ||
+ !$suffix.length ||
+ !$wrapper.length
+ ) {
return;
}
// Skip processing upon a form validation error on the machine name.
@@ -111,15 +122,20 @@
// based on the human-readable form element value.
if ($target.is(':disabled') || $target.val() !== '') {
machine = $target.val();
- }
- else if ($source.val() !== '') {
+ } else if ($source.val() !== '') {
machine = self.transliterate($source.val(), options);
}
// Append the machine name preview to the source field.
- const $preview = $(`<span class="machine-name-value">${options.field_prefix}${Drupal.checkPlain(machine)}${options.field_suffix}</span>`);
+ const $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(
+ `<span class="machine-name-label">${options.label}: </span>`,
+ );
}
$suffix.append($preview);
@@ -137,14 +153,19 @@
options,
};
// If it is editable, append an edit link.
- const $link = $(`<span class="admin-link"><button type="button" class="link">${Drupal.t('Edit')}</button></span>`).on('click', eventData, clickEditHandler);
+ const $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)
+ $source
+ .on('formUpdated.machineName', eventData, machineNameHandler)
// Initialize machine name preview.
.trigger('formUpdated.machineName');
}
@@ -161,11 +182,14 @@
if (machine !== '') {
if (machine !== settings.replace) {
data.$target.val(machine);
- data.$preview.html(settings.field_prefix + Drupal.checkPlain(machine) + settings.field_suffix);
+ data.$preview.html(
+ settings.field_prefix +
+ Drupal.checkPlain(machine) +
+ settings.field_suffix,
+ );
}
data.$suffix.show();
- }
- else {
+ } else {
data.$suffix.hide();
data.$target.val(machine);
data.$preview.empty();
@@ -203,4 +227,4 @@
});
},
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/misc/progress.es6.js b/core/misc/progress.es6.js
index bec63d5..182c9bf 100644
--- a/core/misc/progress.es6.js
+++ b/core/misc/progress.es6.js
@@ -3,7 +3,7 @@
* Progress bar.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Theme function for the progress bar.
*
@@ -13,13 +13,15 @@
* @return {string}
* The HTML for the progress bar.
*/
- Drupal.theme.progressBar = function (id) {
- return `<div id="${id}" class="progress" aria-live="polite">` +
+ Drupal.theme.progressBar = function(id) {
+ return (
+ `<div id="${id}" class="progress" aria-live="polite">` +
'<div class="progress__label">&nbsp;</div>' +
'<div class="progress__track"><div class="progress__bar"></div></div>' +
'<div class="progress__percentage"></div>' +
'<div class="progress__description">&nbsp;</div>' +
- '</div>';
+ '</div>'
+ );
};
/**
@@ -44,7 +46,7 @@
* @param {function} errorCallback
* Callback to call on error.
*/
- Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) {
+ Drupal.ProgressBar = function(id, updateCallback, method, errorCallback) {
this.id = id;
this.method = method || 'GET';
this.updateCallback = updateCallback;
@@ -57,111 +59,124 @@
this.element = $(Drupal.theme('progressBar', id));
};
- $.extend(Drupal.ProgressBar.prototype, /** @lends Drupal.ProgressBar# */{
-
- /**
- * Set the percentage and status message for the progressbar.
- *
- * @param {number} percentage
- * The progress percentage.
- * @param {string} message
- * The message to show the user.
- * @param {string} label
- * The text for the progressbar label.
- */
- setProgress(percentage, message, label) {
- if (percentage >= 0 && percentage <= 100) {
- $(this.element).find('div.progress__bar').css('width', `${percentage}%`);
- $(this.element).find('div.progress__percentage').html(`${percentage}%`);
- }
- $('div.progress__description', this.element).html(message);
- $('div.progress__label', this.element).html(label);
- if (this.updateCallback) {
- this.updateCallback(percentage, message, this);
- }
- },
-
- /**
- * Start monitoring progress via Ajax.
- *
- * @param {string} uri
- * The URI to use for monitoring.
- * @param {number} delay
- * The delay for calling the monitoring URI.
- */
- startMonitoring(uri, delay) {
- this.delay = delay;
- this.uri = uri;
- this.sendPing();
- },
+ $.extend(
+ Drupal.ProgressBar.prototype,
+ /** @lends Drupal.ProgressBar# */ {
+ /**
+ * Set the percentage and status message for the progressbar.
+ *
+ * @param {number} percentage
+ * The progress percentage.
+ * @param {string} message
+ * The message to show the user.
+ * @param {string} label
+ * The text for the progressbar label.
+ */
+ setProgress(percentage, message, label) {
+ if (percentage >= 0 && percentage <= 100) {
+ $(this.element)
+ .find('div.progress__bar')
+ .css('width', `${percentage}%`);
+ $(this.element)
+ .find('div.progress__percentage')
+ .html(`${percentage}%`);
+ }
+ $('div.progress__description', this.element).html(message);
+ $('div.progress__label', this.element).html(label);
+ if (this.updateCallback) {
+ this.updateCallback(percentage, message, this);
+ }
+ },
- /**
- * Stop monitoring progress via Ajax.
- */
- stopMonitoring() {
- clearTimeout(this.timer);
- // This allows monitoring to be stopped from within the callback.
- this.uri = null;
- },
+ /**
+ * Start monitoring progress via Ajax.
+ *
+ * @param {string} uri
+ * The URI to use for monitoring.
+ * @param {number} delay
+ * The delay for calling the monitoring URI.
+ */
+ startMonitoring(uri, delay) {
+ this.delay = delay;
+ this.uri = uri;
+ this.sendPing();
+ },
- /**
- * Request progress data from server.
- */
- sendPing() {
- if (this.timer) {
+ /**
+ * Stop monitoring progress via Ajax.
+ */
+ stopMonitoring() {
clearTimeout(this.timer);
- }
- if (this.uri) {
- const pb = this;
- // When doing a post request, you need non-null data. Otherwise a
- // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
- let uri = this.uri;
- if (uri.indexOf('?') === -1) {
- uri += '?';
+ // This allows monitoring to be stopped from within the callback.
+ this.uri = null;
+ },
+
+ /**
+ * Request progress data from server.
+ */
+ sendPing() {
+ if (this.timer) {
+ clearTimeout(this.timer);
}
- else {
- uri += '&';
+ if (this.uri) {
+ const pb = this;
+ // When doing a post request, you need non-null data. Otherwise a
+ // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
+ let uri = this.uri;
+ if (uri.indexOf('?') === -1) {
+ uri += '?';
+ } else {
+ uri += '&';
+ }
+ uri += '_format=json';
+ $.ajax({
+ type: this.method,
+ url: uri,
+ data: '',
+ dataType: 'json',
+ success(progress) {
+ // Display errors.
+ if (progress.status === 0) {
+ pb.displayError(progress.data);
+ return;
+ }
+ // Update display.
+ pb.setProgress(
+ progress.percentage,
+ progress.message,
+ progress.label,
+ );
+ // Schedule next timer.
+ pb.timer = setTimeout(() => {
+ pb.sendPing();
+ }, pb.delay);
+ },
+ error(xmlhttp) {
+ const e = new Drupal.AjaxError(xmlhttp, pb.uri);
+ pb.displayError(`<pre>${e.message}</pre>`);
+ },
+ });
}
- uri += '_format=json';
- $.ajax({
- type: this.method,
- url: uri,
- data: '',
- dataType: 'json',
- success(progress) {
- // Display errors.
- if (progress.status === 0) {
- pb.displayError(progress.data);
- return;
- }
- // Update display.
- pb.setProgress(progress.percentage, progress.message, progress.label);
- // Schedule next timer.
- pb.timer = setTimeout(() => {
- pb.sendPing();
- }, pb.delay);
- },
- error(xmlhttp) {
- const e = new Drupal.AjaxError(xmlhttp, pb.uri);
- pb.displayError(`<pre>${e.message}</pre>`);
- },
- });
- }
- },
+ },
- /**
- * Display errors on the page.
- *
- * @param {string} string
- * The error message to show the user.
- */
- displayError(string) {
- const error = $('<div class="messages messages--error"></div>').html(string);
- $(this.element).before(error).hide();
+ /**
+ * Display errors on the page.
+ *
+ * @param {string} string
+ * The error message to show the user.
+ */
+ displayError(string) {
+ const error = $('<div class="messages messages--error"></div>').html(
+ string,
+ );
+ $(this.element)
+ .before(error)
+ .hide();
- if (this.errorCallback) {
- this.errorCallback(this);
- }
+ if (this.errorCallback) {
+ this.errorCallback(this);
+ }
+ },
},
- });
-}(jQuery, Drupal));
+ );
+})(jQuery, Drupal);
diff --git a/core/misc/states.es6.js b/core/misc/states.es6.js
index 335d8ed..dd2c315 100644
--- a/core/misc/states.es6.js
+++ b/core/misc/states.es6.js
@@ -3,7 +3,7 @@
* Drupal's states library.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* The base States namespace.
*
@@ -13,7 +13,6 @@
* @namespace Drupal.states
*/
const states = {
-
/**
* An array of functions that should be postponed.
*/
@@ -36,7 +35,7 @@
* The result.
*/
function invert(a, invertState) {
- return (invertState && typeof a !== 'undefined') ? !a : a;
+ return invertState && typeof a !== 'undefined' ? !a : a;
}
/**
@@ -73,8 +72,10 @@
const $states = $(context).find('[data-drupal-states]');
const il = $states.length;
for (let i = 0; i < il; i++) {
- const config = JSON.parse($states[i].getAttribute('data-drupal-states'));
- Object.keys(config || {}).forEach((state) => {
+ const config = JSON.parse(
+ $states[i].getAttribute('data-drupal-states'),
+ );
+ Object.keys(config || {}).forEach(state => {
new states.Dependent({
element: $($states[i]),
state: states.State.sanitize(state),
@@ -85,7 +86,7 @@
// Execute all postponed functions now.
while (states.postponed.length) {
- (states.postponed.shift())();
+ states.postponed.shift()();
}
},
};
@@ -106,11 +107,11 @@
* element depends on. It can be nested and can contain
* arbitrary AND and OR clauses.
*/
- states.Dependent = function (args) {
+ states.Dependent = function(args) {
$.extend(this, { values: {}, oldValue: null }, args);
this.dependees = this.getDependees();
- Object.keys(this.dependees || {}).forEach((selector) => {
+ Object.keys(this.dependees || {}).forEach(selector => {
this.initializeDependee(selector, this.dependees[selector]);
});
};
@@ -140,12 +141,13 @@
// compare().
// Otherwise numeric keys in the form's #states array fail to match
// string values returned from jQuery's val().
- return (typeof value === 'string') ? compare(reference.toString(), value) : compare(reference, value);
+ return typeof value === 'string'
+ ? compare(reference.toString(), value)
+ : compare(reference, value);
},
};
states.Dependent.prototype = {
-
/**
* Initializes one of the elements this dependent depends on.
*
@@ -161,7 +163,7 @@
// Cache for the states of this dependee.
this.values[selector] = {};
- Object.keys(dependeeStates).forEach((i) => {
+ Object.keys(dependeeStates).forEach(i => {
let state = dependeeStates[i];
// Make sure we're not initializing this selector/state combination
// twice.
@@ -175,7 +177,7 @@
this.values[selector][state.name] = null;
// Monitor state changes of the specified state for this dependee.
- $(selector).on(`state:${state}`, { selector, state }, (e) => {
+ $(selector).on(`state:${state}`, { selector, state }, e => {
this.update(e.data.selector, e.data.state, e.value);
});
@@ -203,7 +205,10 @@
const value = this.values[selector][state.name];
if (reference.constructor.name in states.Dependent.comparisons) {
// Use a custom compare function for certain reference value types.
- return states.Dependent.comparisons[reference.constructor.name](reference, value);
+ return states.Dependent.comparisons[reference.constructor.name](
+ reference,
+ value,
+ );
}
// Do a plain comparison otherwise.
@@ -250,7 +255,11 @@
// By adding "trigger: true", we ensure that state changes don't go into
// infinite loops.
- this.element.trigger({ type: `state:${this.state}`, value, trigger: true });
+ this.element.trigger({
+ type: `state:${this.state}`,
+ value,
+ trigger: true,
+ });
}
},
@@ -277,7 +286,11 @@
const len = constraints.length;
for (let i = 0; i < len; i++) {
if (constraints[i] !== 'xor') {
- const constraint = this.checkConstraints(constraints[i], selector, i);
+ const constraint = this.checkConstraints(
+ constraints[i],
+ selector,
+ i,
+ );
// Return if this is OR and we have a satisfied constraint or if
// this is XOR and we have a second satisfied constraint.
if (constraint && (hasXor || result)) {
@@ -292,7 +305,7 @@
// bogus, we don't want to end up with an infinite loop.
else if ($.isPlainObject(constraints)) {
// This constraint is an object (AND).
- result = Object.keys(constraints).every((constraint) => {
+ result = Object.keys(constraints).every(constraint => {
const check = this.checkConstraints(
constraints[constraint],
selector,
@@ -333,10 +346,9 @@
checkConstraints(value, selector, state) {
// Normalize the last parameter. If it's non-numeric, we treat it either
// as a selector (in case there isn't one yet) or as a trigger/state.
- if (typeof state !== 'string' || (/[0-9]/).test(state[0])) {
+ if (typeof state !== 'string' || /[0-9]/.test(state[0])) {
state = null;
- }
- else if (typeof selector === 'undefined') {
+ } else if (typeof selector === 'undefined') {
// Propagate the state to the selector when there isn't one yet.
selector = state;
state = null;
@@ -365,7 +377,7 @@
// Swivel the lookup function so that we can record all available
// selector- state combinations for initialization.
const _compare = this.compare;
- this.compare = function (reference, selector, state) {
+ this.compare = function(reference, selector, state) {
(cache[selector] || (cache[selector] = [])).push(state.name);
// Return nothing (=== undefined) so that the constraint loops are not
// broken.
@@ -391,7 +403,7 @@
* @param {object} args
* Trigger arguments.
*/
- states.Trigger = function (args) {
+ states.Trigger = function(args) {
$.extend(this, args);
if (this.state in states.Trigger.states) {
@@ -406,7 +418,6 @@
};
states.Trigger.prototype = {
-
/**
* @memberof Drupal.states.Trigger#
*/
@@ -416,9 +427,8 @@
if (typeof trigger === 'function') {
// We have a custom trigger initialization function.
trigger.call(window, this.element);
- }
- else {
- Object.keys(trigger || {}).forEach((event) => {
+ } else {
+ Object.keys(trigger || {}).forEach(event => {
this.defaultTrigger(event, trigger[event]);
});
}
@@ -439,19 +449,32 @@
let oldValue = valueFn.call(this.element);
// Attach the event callback.
- this.element.on(event, $.proxy(function (e) {
- const value = valueFn.call(this.element, e);
- // Only trigger the event if the value has actually changed.
- if (oldValue !== value) {
- this.element.trigger({ type: `state:${this.state}`, value, oldValue });
- oldValue = value;
- }
- }, this));
-
- states.postponed.push($.proxy(function () {
- // Trigger the event once for initialization purposes.
- this.element.trigger({ type: `state:${this.state}`, value: oldValue, oldValue: null });
- }, this));
+ this.element.on(
+ event,
+ $.proxy(function(e) {
+ const value = valueFn.call(this.element, e);
+ // Only trigger the event if the value has actually changed.
+ if (oldValue !== value) {
+ this.element.trigger({
+ type: `state:${this.state}`,
+ value,
+ oldValue,
+ });
+ oldValue = value;
+ }
+ }, this),
+ );
+
+ states.postponed.push(
+ $.proxy(function() {
+ // Trigger the event once for initialization purposes.
+ this.element.trigger({
+ type: `state:${this.state}`,
+ value: oldValue,
+ oldValue: null,
+ });
+ }, this),
+ );
},
};
@@ -485,7 +508,7 @@
// support selectors matching multiple checkboxes, iterate over all and
// return whether any is checked.
let checked = false;
- this.each(function () {
+ this.each(function() {
// Use prop() here as we want a boolean of the checkbox state.
// @see http://api.jquery.com/prop/
checked = $(this).prop('checked');
@@ -518,7 +541,9 @@
collapsed: {
collapsed(e) {
- return (typeof e !== 'undefined' && 'value' in e) ? e.value : !this.is('[open]');
+ return typeof e !== 'undefined' && 'value' in e
+ ? e.value
+ : !this.is('[open]');
},
},
};
@@ -531,7 +556,7 @@
* @param {string} state
* The name of the state.
*/
- states.State = function (state) {
+ states.State = function(state) {
/**
* Original unresolved name.
*/
@@ -550,8 +575,7 @@
// Replace the state with its normalized name.
if (this.name in states.State.aliases) {
this.name = states.State.aliases[this.name];
- }
- else {
+ } else {
process = false;
}
} while (process);
@@ -568,7 +592,7 @@
* @return {Drupal.states.state}
* A state object.
*/
- states.State.sanitize = function (state) {
+ states.State.sanitize = function(state) {
if (state instanceof states.State) {
return state;
}
@@ -598,7 +622,6 @@
};
states.State.prototype = {
-
/**
* @memberof Drupal.states.State#
*/
@@ -625,7 +648,7 @@
*/
const $document = $(document);
- $document.on('state:disabled', (e) => {
+ $document.on('state:disabled', e => {
// Only act when this change was triggered by a dependency and not by the
// element monitoring itself.
if (e.trigger) {
@@ -641,17 +664,19 @@
}
});
- $document.on('state:required', (e) => {
+ $document.on('state:required', e => {
if (e.trigger) {
if (e.value) {
const label = `label${e.target.id ? `[for=${e.target.id}]` : ''}`;
- const $label = $(e.target).attr({ required: 'required', 'aria-required': 'aria-required' }).closest('.js-form-item, .js-form-wrapper').find(label);
+ const $label = $(e.target)
+ .attr({ required: 'required', 'aria-required': 'aria-required' })
+ .closest('.js-form-item, .js-form-wrapper')
+ .find(label);
// Avoids duplicate required markers on initialization.
if (!$label.hasClass('js-form-required').length) {
$label.addClass('js-form-required form-required');
}
- }
- else {
+ } else {
$(e.target)
.removeAttr('required aria-required')
.closest('.js-form-item, .js-form-wrapper')
@@ -661,23 +686,27 @@
}
});
- $document.on('state:visible', (e) => {
+ $document.on('state:visible', e => {
if (e.trigger) {
- $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value);
+ $(e.target)
+ .closest('.js-form-item, .js-form-submit, .js-form-wrapper')
+ .toggle(e.value);
}
});
- $document.on('state:checked', (e) => {
+ $document.on('state:checked', e => {
if (e.trigger) {
$(e.target).prop('checked', e.value);
}
});
- $document.on('state:collapsed', (e) => {
+ $document.on('state:collapsed', e => {
if (e.trigger) {
if ($(e.target).is('[open]') === e.value) {
- $(e.target).find('> summary').trigger('click');
+ $(e.target)
+ .find('> summary')
+ .trigger('click');
}
}
});
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/states.js b/core/misc/states.js
index a8c5802..fcdc37a 100644
--- a/core/misc/states.js
+++ b/core/misc/states.js
@@ -119,7 +119,11 @@
value = invert(value, this.state.invert);
- this.element.trigger({ type: 'state:' + this.state, value: value, trigger: true });
+ this.element.trigger({
+ type: 'state:' + this.state,
+ value: value,
+ trigger: true
+ });
}
},
verifyConstraints: function verifyConstraints(constraints, selector) {
@@ -214,13 +218,21 @@
var value = valueFn.call(this.element, e);
if (oldValue !== value) {
- this.element.trigger({ type: 'state:' + this.state, value: value, oldValue: oldValue });
+ this.element.trigger({
+ type: 'state:' + this.state,
+ value: value,
+ oldValue: oldValue
+ });
oldValue = value;
}
}, this));
states.postponed.push($.proxy(function () {
- this.element.trigger({ type: 'state:' + this.state, value: oldValue, oldValue: null });
+ this.element.trigger({
+ type: 'state:' + this.state,
+ value: oldValue,
+ oldValue: null
+ });
}, this));
}
};
diff --git a/core/misc/tabbingmanager.es6.js b/core/misc/tabbingmanager.es6.js
index 5183d8b..5f41471 100644
--- a/core/misc/tabbingmanager.es6.js
+++ b/core/misc/tabbingmanager.es6.js
@@ -27,7 +27,7 @@
* @event drupalTabbingContextDeactivated
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Provides an API for managing page tabbing order modifications.
*
@@ -72,283 +72,289 @@
* tabbingContext can be active at a time.
*/
function TabbingContext(options) {
- $.extend(this, /** @lends Drupal~TabbingContext# */{
-
- /**
- * @type {?number}
- */
- level: null,
-
- /**
- * @type {jQuery}
- */
- $tabbableElements: $(),
-
- /**
- * @type {jQuery}
- */
- $disabledElements: $(),
-
- /**
- * @type {bool}
- */
- released: false,
-
- /**
- * @type {bool}
- */
- active: false,
- }, options);
+ $.extend(
+ this,
+ /** @lends Drupal~TabbingContext# */ {
+ /**
+ * @type {?number}
+ */
+ level: null,
+
+ /**
+ * @type {jQuery}
+ */
+ $tabbableElements: $(),
+
+ /**
+ * @type {jQuery}
+ */
+ $disabledElements: $(),
+
+ /**
+ * @type {bool}
+ */
+ released: false,
+
+ /**
+ * @type {bool}
+ */
+ active: false,
+ },
+ options,
+ );
}
/**
* Add public methods to the TabbingManager class.
*/
- $.extend(TabbingManager.prototype, /** @lends Drupal~TabbingManager# */{
-
- /**
- * Constrain tabbing to the specified set of elements only.
- *
- * Makes elements outside of the specified set of elements unreachable via
- * the tab key.
- *
- * @param {jQuery} elements
- * The set of elements to which tabbing should be constrained. Can also
- * be a jQuery-compatible selector string.
- *
- * @return {Drupal~TabbingContext}
- * The TabbingContext instance.
- *
- * @fires event:drupalTabbingConstrained
- */
- constrain(elements) {
- // Deactivate all tabbingContexts to prepare for the new constraint. A
- // tabbingContext instance will only be reactivated if the stack is
- // unwound to it in the _unwindStack() method.
- const il = this.stack.length;
- for (let i = 0; i < il; i++) {
- this.stack[i].deactivate();
- }
-
- // The "active tabbing set" are the elements tabbing should be constrained
- // to.
- const $elements = $(elements).find(':tabbable').addBack(':tabbable');
-
- const tabbingContext = new TabbingContext({
- // The level is the current height of the stack before this new
- // tabbingContext is pushed on top of the stack.
- level: this.stack.length,
- $tabbableElements: $elements,
- });
-
- this.stack.push(tabbingContext);
-
- // Activates the tabbingContext; this will manipulate the DOM to constrain
- // tabbing.
- tabbingContext.activate();
-
- // Allow modules to respond to the constrain event.
- $(document).trigger('drupalTabbingConstrained', tabbingContext);
+ $.extend(
+ TabbingManager.prototype,
+ /** @lends Drupal~TabbingManager# */ {
+ /**
+ * Constrain tabbing to the specified set of elements only.
+ *
+ * Makes elements outside of the specified set of elements unreachable via
+ * the tab key.
+ *
+ * @param {jQuery} elements
+ * The set of elements to which tabbing should be constrained. Can also
+ * be a jQuery-compatible selector string.
+ *
+ * @return {Drupal~TabbingContext}
+ * The TabbingContext instance.
+ *
+ * @fires event:drupalTabbingConstrained
+ */
+ constrain(elements) {
+ // Deactivate all tabbingContexts to prepare for the new constraint. A
+ // tabbingContext instance will only be reactivated if the stack is
+ // unwound to it in the _unwindStack() method.
+ const il = this.stack.length;
+ for (let i = 0; i < il; i++) {
+ this.stack[i].deactivate();
+ }
- return tabbingContext;
- },
+ // The "active tabbing set" are the elements tabbing should be constrained
+ // to.
+ const $elements = $(elements)
+ .find(':tabbable')
+ .addBack(':tabbable');
- /**
- * Restores a former tabbingContext when an active one is released.
- *
- * The TabbingManager stack of tabbingContext instances will be unwound
- * from the top-most released tabbingContext down to the first non-released
- * tabbingContext instance. This non-released instance is then activated.
- */
- release() {
- // Unwind as far as possible: find the topmost non-released
- // tabbingContext.
- let toActivate = this.stack.length - 1;
- while (toActivate >= 0 && this.stack[toActivate].released) {
- toActivate--;
- }
+ const tabbingContext = new TabbingContext({
+ // The level is the current height of the stack before this new
+ // tabbingContext is pushed on top of the stack.
+ level: this.stack.length,
+ $tabbableElements: $elements,
+ });
- // Delete all tabbingContexts after the to be activated one. They have
- // already been deactivated, so their effect on the DOM has been reversed.
- this.stack.splice(toActivate + 1);
+ this.stack.push(tabbingContext);
- // Get topmost tabbingContext, if one exists, and activate it.
- if (toActivate >= 0) {
- this.stack[toActivate].activate();
- }
- },
+ // Activates the tabbingContext; this will manipulate the DOM to constrain
+ // tabbing.
+ tabbingContext.activate();
- /**
- * Makes all elements outside of the tabbingContext's set untabbable.
- *
- * Elements made untabbable have their original tabindex and autofocus
- * values stored so that they might be restored later when this
- * tabbingContext is deactivated.
- *
- * @param {Drupal~TabbingContext} tabbingContext
- * The TabbingContext instance that has been activated.
- */
- activate(tabbingContext) {
- const $set = tabbingContext.$tabbableElements;
- const level = tabbingContext.level;
- // Determine which elements are reachable via tabbing by default.
- const $disabledSet = $(':tabbable')
- // Exclude elements of the active tabbing set.
- .not($set);
- // Set the disabled set on the tabbingContext.
- tabbingContext.$disabledElements = $disabledSet;
- // Record the tabindex for each element, so we can restore it later.
- const il = $disabledSet.length;
- for (let i = 0; i < il; i++) {
- this.recordTabindex($disabledSet.eq(i), level);
- }
- // Make all tabbable elements outside of the active tabbing set
- // unreachable.
- $disabledSet
- .prop('tabindex', -1)
- .prop('autofocus', false);
+ // Allow modules to respond to the constrain event.
+ $(document).trigger('drupalTabbingConstrained', tabbingContext);
- // Set focus on an element in the tabbingContext's set of tabbable
- // elements. First, check if there is an element with an autofocus
- // attribute. Select the last one from the DOM order.
- let $hasFocus = $set.filter('[autofocus]').eq(-1);
- // If no element in the tabbable set has an autofocus attribute, select
- // the first element in the set.
- if ($hasFocus.length === 0) {
- $hasFocus = $set.eq(0);
- }
- $hasFocus.trigger('focus');
- },
+ return tabbingContext;
+ },
- /**
- * Restores that tabbable state of a tabbingContext's disabled elements.
- *
- * Elements that were made untabbable have their original tabindex and
- * autofocus values restored.
- *
- * @param {Drupal~TabbingContext} tabbingContext
- * The TabbingContext instance that has been deactivated.
- */
- deactivate(tabbingContext) {
- const $set = tabbingContext.$disabledElements;
- const level = tabbingContext.level;
- const il = $set.length;
- for (let i = 0; i < il; i++) {
- this.restoreTabindex($set.eq(i), level);
- }
- },
+ /**
+ * Restores a former tabbingContext when an active one is released.
+ *
+ * The TabbingManager stack of tabbingContext instances will be unwound
+ * from the top-most released tabbingContext down to the first non-released
+ * tabbingContext instance. This non-released instance is then activated.
+ */
+ release() {
+ // Unwind as far as possible: find the topmost non-released
+ // tabbingContext.
+ let toActivate = this.stack.length - 1;
+ while (toActivate >= 0 && this.stack[toActivate].released) {
+ toActivate--;
+ }
- /**
- * Records the tabindex and autofocus values of an untabbable element.
- *
- * @param {jQuery} $el
- * The set of elements that have been disabled.
- * @param {number} level
- * The stack level for which the tabindex attribute should be recorded.
- */
- recordTabindex($el, level) {
- const tabInfo = $el.data('drupalOriginalTabIndices') || {};
- tabInfo[level] = {
- tabindex: $el[0].getAttribute('tabindex'),
- autofocus: $el[0].hasAttribute('autofocus'),
- };
- $el.data('drupalOriginalTabIndices', tabInfo);
- },
+ // Delete all tabbingContexts after the to be activated one. They have
+ // already been deactivated, so their effect on the DOM has been reversed.
+ this.stack.splice(toActivate + 1);
- /**
- * Restores the tabindex and autofocus values of a reactivated element.
- *
- * @param {jQuery} $el
- * The element that is being reactivated.
- * @param {number} level
- * The stack level for which the tabindex attribute should be restored.
- */
- restoreTabindex($el, level) {
- const tabInfo = $el.data('drupalOriginalTabIndices');
- if (tabInfo && tabInfo[level]) {
- const data = tabInfo[level];
- if (data.tabindex) {
- $el[0].setAttribute('tabindex', data.tabindex);
+ // Get topmost tabbingContext, if one exists, and activate it.
+ if (toActivate >= 0) {
+ this.stack[toActivate].activate();
}
- // If the element did not have a tabindex at this stack level then
- // remove it.
- else {
- $el[0].removeAttribute('tabindex');
+ },
+
+ /**
+ * Makes all elements outside of the tabbingContext's set untabbable.
+ *
+ * Elements made untabbable have their original tabindex and autofocus
+ * values stored so that they might be restored later when this
+ * tabbingContext is deactivated.
+ *
+ * @param {Drupal~TabbingContext} tabbingContext
+ * The TabbingContext instance that has been activated.
+ */
+ activate(tabbingContext) {
+ const $set = tabbingContext.$tabbableElements;
+ const level = tabbingContext.level;
+ // Determine which elements are reachable via tabbing by default.
+ const $disabledSet = $(':tabbable')
+ // Exclude elements of the active tabbing set.
+ .not($set);
+ // Set the disabled set on the tabbingContext.
+ tabbingContext.$disabledElements = $disabledSet;
+ // Record the tabindex for each element, so we can restore it later.
+ const il = $disabledSet.length;
+ for (let i = 0; i < il; i++) {
+ this.recordTabindex($disabledSet.eq(i), level);
}
- if (data.autofocus) {
- $el[0].setAttribute('autofocus', 'autofocus');
+ // Make all tabbable elements outside of the active tabbing set
+ // unreachable.
+ $disabledSet.prop('tabindex', -1).prop('autofocus', false);
+
+ // Set focus on an element in the tabbingContext's set of tabbable
+ // elements. First, check if there is an element with an autofocus
+ // attribute. Select the last one from the DOM order.
+ let $hasFocus = $set.filter('[autofocus]').eq(-1);
+ // If no element in the tabbable set has an autofocus attribute, select
+ // the first element in the set.
+ if ($hasFocus.length === 0) {
+ $hasFocus = $set.eq(0);
}
+ $hasFocus.trigger('focus');
+ },
- // Clean up $.data.
- if (level === 0) {
- // Remove all data.
- $el.removeData('drupalOriginalTabIndices');
+ /**
+ * Restores that tabbable state of a tabbingContext's disabled elements.
+ *
+ * Elements that were made untabbable have their original tabindex and
+ * autofocus values restored.
+ *
+ * @param {Drupal~TabbingContext} tabbingContext
+ * The TabbingContext instance that has been deactivated.
+ */
+ deactivate(tabbingContext) {
+ const $set = tabbingContext.$disabledElements;
+ const level = tabbingContext.level;
+ const il = $set.length;
+ for (let i = 0; i < il; i++) {
+ this.restoreTabindex($set.eq(i), level);
}
- else {
- // Remove the data for this stack level and higher.
- let levelToDelete = level;
- while (tabInfo.hasOwnProperty(levelToDelete)) {
- delete tabInfo[levelToDelete];
- levelToDelete++;
+ },
+
+ /**
+ * Records the tabindex and autofocus values of an untabbable element.
+ *
+ * @param {jQuery} $el
+ * The set of elements that have been disabled.
+ * @param {number} level
+ * The stack level for which the tabindex attribute should be recorded.
+ */
+ recordTabindex($el, level) {
+ const tabInfo = $el.data('drupalOriginalTabIndices') || {};
+ tabInfo[level] = {
+ tabindex: $el[0].getAttribute('tabindex'),
+ autofocus: $el[0].hasAttribute('autofocus'),
+ };
+ $el.data('drupalOriginalTabIndices', tabInfo);
+ },
+
+ /**
+ * Restores the tabindex and autofocus values of a reactivated element.
+ *
+ * @param {jQuery} $el
+ * The element that is being reactivated.
+ * @param {number} level
+ * The stack level for which the tabindex attribute should be restored.
+ */
+ restoreTabindex($el, level) {
+ const tabInfo = $el.data('drupalOriginalTabIndices');
+ if (tabInfo && tabInfo[level]) {
+ const data = tabInfo[level];
+ if (data.tabindex) {
+ $el[0].setAttribute('tabindex', data.tabindex);
+ }
+ // If the element did not have a tabindex at this stack level then
+ // remove it.
+ else {
+ $el[0].removeAttribute('tabindex');
+ }
+ if (data.autofocus) {
+ $el[0].setAttribute('autofocus', 'autofocus');
+ }
+
+ // Clean up $.data.
+ if (level === 0) {
+ // Remove all data.
+ $el.removeData('drupalOriginalTabIndices');
+ } else {
+ // Remove the data for this stack level and higher.
+ let levelToDelete = level;
+ while (tabInfo.hasOwnProperty(levelToDelete)) {
+ delete tabInfo[levelToDelete];
+ levelToDelete++;
+ }
+ $el.data('drupalOriginalTabIndices', tabInfo);
}
- $el.data('drupalOriginalTabIndices', tabInfo);
}
- }
+ },
},
- });
+ );
/**
* Add public methods to the TabbingContext class.
*/
- $.extend(TabbingContext.prototype, /** @lends Drupal~TabbingContext# */{
-
- /**
- * Releases this TabbingContext.
- *
- * Once a TabbingContext object is released, it can never be activated
- * again.
- *
- * @fires event:drupalTabbingContextReleased
- */
- release() {
- if (!this.released) {
- this.deactivate();
- this.released = true;
- Drupal.tabbingManager.release(this);
- // Allow modules to respond to the tabbingContext release event.
- $(document).trigger('drupalTabbingContextReleased', this);
- }
- },
+ $.extend(
+ TabbingContext.prototype,
+ /** @lends Drupal~TabbingContext# */ {
+ /**
+ * Releases this TabbingContext.
+ *
+ * Once a TabbingContext object is released, it can never be activated
+ * again.
+ *
+ * @fires event:drupalTabbingContextReleased
+ */
+ release() {
+ if (!this.released) {
+ this.deactivate();
+ this.released = true;
+ Drupal.tabbingManager.release(this);
+ // Allow modules to respond to the tabbingContext release event.
+ $(document).trigger('drupalTabbingContextReleased', this);
+ }
+ },
- /**
- * Activates this TabbingContext.
- *
- * @fires event:drupalTabbingContextActivated
- */
- activate() {
- // A released TabbingContext object can never be activated again.
- if (!this.active && !this.released) {
- this.active = true;
- Drupal.tabbingManager.activate(this);
- // Allow modules to respond to the constrain event.
- $(document).trigger('drupalTabbingContextActivated', this);
- }
- },
+ /**
+ * Activates this TabbingContext.
+ *
+ * @fires event:drupalTabbingContextActivated
+ */
+ activate() {
+ // A released TabbingContext object can never be activated again.
+ if (!this.active && !this.released) {
+ this.active = true;
+ Drupal.tabbingManager.activate(this);
+ // Allow modules to respond to the constrain event.
+ $(document).trigger('drupalTabbingContextActivated', this);
+ }
+ },
- /**
- * Deactivates this TabbingContext.
- *
- * @fires event:drupalTabbingContextDeactivated
- */
- deactivate() {
- if (this.active) {
- this.active = false;
- Drupal.tabbingManager.deactivate(this);
- // Allow modules to respond to the constrain event.
- $(document).trigger('drupalTabbingContextDeactivated', this);
- }
+ /**
+ * Deactivates this TabbingContext.
+ *
+ * @fires event:drupalTabbingContextDeactivated
+ */
+ deactivate() {
+ if (this.active) {
+ this.active = false;
+ Drupal.tabbingManager.deactivate(this);
+ // Allow modules to respond to the constrain event.
+ $(document).trigger('drupalTabbingContextDeactivated', this);
+ }
+ },
},
- });
+ );
// Mark this behavior as processed on the first pass and return if it is
// already processed.
@@ -360,4 +366,4 @@
* @type {Drupal~TabbingManager}
*/
Drupal.tabbingManager = new TabbingManager();
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/tabledrag.es6.js b/core/misc/tabledrag.es6.js
index 2010624..76643c3 100644
--- a/core/misc/tabledrag.es6.js
+++ b/core/misc/tabledrag.es6.js
@@ -9,13 +9,15 @@
* @event columnschange
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Store the state of weight columns display for all tables.
*
* Default value is to hide weight columns.
*/
- let showWeight = JSON.parse(localStorage.getItem('Drupal.tableDrag.showWeight'));
+ let showWeight = JSON.parse(
+ localStorage.getItem('Drupal.tableDrag.showWeight'),
+ );
/**
* Drag and drop table rows with field manipulation.
@@ -37,12 +39,20 @@
if (table.length) {
// Create the new tableDrag instance. Save in the Drupal variable
// to allow other scripts access to the object.
- Drupal.tableDrag[base] = new Drupal.tableDrag(table[0], settings.tableDrag[base]);
+ Drupal.tableDrag[base] = new Drupal.tableDrag(
+ table[0],
+ settings.tableDrag[base],
+ );
}
}
- Object.keys(settings.tableDrag || {}).forEach((base) => {
- initTableDrag($(context).find(`#${base}`).once('tabledrag'), base);
+ Object.keys(settings.tableDrag || {}).forEach(base => {
+ initTableDrag(
+ $(context)
+ .find(`#${base}`)
+ .once('tabledrag'),
+ base,
+ );
});
},
};
@@ -57,7 +67,7 @@
* @param {object} tableSettings
* Settings for the table added via drupal_add_dragtable().
*/
- Drupal.tableDrag = function (table, tableSettings) {
+ Drupal.tableDrag = function(table, tableSettings) {
const self = this;
const $table = $(table);
@@ -170,8 +180,8 @@
* @type {bool}
*/
this.indentEnabled = false;
- Object.keys(tableSettings || {}).forEach((group) => {
- Object.keys(tableSettings[group] || {}).forEach((n) => {
+ Object.keys(tableSettings || {}).forEach(group => {
+ Object.keys(tableSettings[group] || {}).forEach(n => {
if (tableSettings[group][n].relationship === 'parent') {
this.indentEnabled = true;
}
@@ -192,32 +202,44 @@
// manually append 2 indentations in the first draggable row, measure
// the offset, then remove.
const indent = Drupal.theme('tableDragIndentation');
- const testRow = $('<tr/>').addClass('draggable').appendTo(table);
- const testCell = $('<td/>').appendTo(testRow).prepend(indent).prepend(indent);
+ const testRow = $('<tr/>')
+ .addClass('draggable')
+ .appendTo(table);
+ const testCell = $('<td/>')
+ .appendTo(testRow)
+ .prepend(indent)
+ .prepend(indent);
const $indentation = testCell.find('.js-indentation');
/**
*
* @type {number}
*/
- this.indentAmount = $indentation.get(1).offsetLeft - $indentation.get(0).offsetLeft;
+ this.indentAmount =
+ $indentation.get(1).offsetLeft - $indentation.get(0).offsetLeft;
testRow.remove();
}
// Make each applicable row draggable.
// Match immediate children of the parent element to allow nesting.
- $table.find('> tr.draggable, > tbody > tr.draggable').each(function () {
+ $table.find('> tr.draggable, > tbody > tr.draggable').each(function() {
self.makeDraggable(this);
});
// Add a link before the table for users to show or hide weight columns.
$table.before(
$('<button type="button" class="link tabledrag-toggle-weight"></button>')
- .attr('title', Drupal.t('Re-order rows by numerical weight instead of dragging.'))
- .on('click', $.proxy(function (e) {
- e.preventDefault();
- this.toggleColumns();
- }, this))
+ .attr(
+ 'title',
+ Drupal.t('Re-order rows by numerical weight instead of dragging.'),
+ )
+ .on(
+ 'click',
+ $.proxy(function(e) {
+ e.preventDefault();
+ this.toggleColumns();
+ }, this),
+ )
.wrap('<div class="tabledrag-toggle-weight-wrapper"></div>')
.parent(),
);
@@ -230,21 +252,28 @@
// Add event bindings to the document. The self variable is passed along
// as event handlers do not have direct access to the tableDrag object.
- $(document).on('touchmove', event => self.dragRow(event.originalEvent.touches[0], self));
- $(document).on('touchend', event => self.dropRow(event.originalEvent.touches[0], self));
+ $(document).on('touchmove', event =>
+ self.dragRow(event.originalEvent.touches[0], self),
+ );
+ $(document).on('touchend', event =>
+ self.dropRow(event.originalEvent.touches[0], self),
+ );
$(document).on('mousemove pointermove', event => self.dragRow(event, self));
$(document).on('mouseup pointerup', event => self.dropRow(event, self));
// React to localStorage event showing or hiding weight columns.
- $(window).on('storage', $.proxy(function (e) {
- // Only react to 'Drupal.tableDrag.showWeight' value change.
- if (e.originalEvent.key === 'Drupal.tableDrag.showWeight') {
- // This was changed in another window, get the new value for this
- // window.
- showWeight = JSON.parse(e.originalEvent.newValue);
- this.displayColumns(showWeight);
- }
- }, this));
+ $(window).on(
+ 'storage',
+ $.proxy(function(e) {
+ // Only react to 'Drupal.tableDrag.showWeight' value change.
+ if (e.originalEvent.key === 'Drupal.tableDrag.showWeight') {
+ // This was changed in another window, get the new value for this
+ // window.
+ showWeight = JSON.parse(e.originalEvent.newValue);
+ this.displayColumns(showWeight);
+ }
+ }, this),
+ );
};
/**
@@ -254,15 +283,17 @@
* show/hide it. Finally, hide columns if user does not have a
* 'Drupal.tableDrag.showWeight' localStorage value.
*/
- Drupal.tableDrag.prototype.initColumns = function () {
+ Drupal.tableDrag.prototype.initColumns = function() {
const $table = this.$table;
let hidden;
let cell;
let columnIndex;
- Object.keys(this.tableSettings || {}).forEach((group) => {
+ Object.keys(this.tableSettings || {}).forEach(group => {
// Find the first field in this group.
- Object.keys(this.tableSettings[group]).some((tableSetting) => {
- const field = $table.find(`.${this.tableSettings[group][tableSetting].target}`).eq(0);
+ Object.keys(this.tableSettings[group]).some(tableSetting => {
+ const field = $table
+ .find(`.${this.tableSettings[group][tableSetting].target}`)
+ .eq(0);
if (field.length && this.tableSettings[group][tableSetting].hidden) {
hidden = this.tableSettings[group][tableSetting].hidden;
cell = field.closest('td');
@@ -276,8 +307,14 @@
// Add 1 to our indexes. The nth-child selector is 1 based, not 0
// based. Match immediate children of the parent element to allow
// nesting.
- columnIndex = cell.parent().find('> td').index(cell.get(0)) + 1;
- $table.find('> thead > tr, > tbody > tr, > tr').each(this.addColspanClass(columnIndex));
+ columnIndex =
+ cell
+ .parent()
+ .find('> td')
+ .index(cell.get(0)) + 1;
+ $table
+ .find('> thead > tr, > tbody > tr, > tr')
+ .each(this.addColspanClass(columnIndex));
}
});
this.displayColumns(showWeight);
@@ -294,14 +331,14 @@
* @return {function}
* Function to add colspan class.
*/
- Drupal.tableDrag.prototype.addColspanClass = function (columnIndex) {
- return function () {
+ Drupal.tableDrag.prototype.addColspanClass = function(columnIndex) {
+ return function() {
// Get the columnIndex and adjust for any colspans in this row.
const $row = $(this);
let index = columnIndex;
const cells = $row.children();
let cell;
- cells.each(function (n) {
+ cells.each(function(n) {
if (n < index && this.colSpan && this.colSpan > 1) {
index -= this.colSpan - 1;
}
@@ -311,8 +348,7 @@
if (cell[0].colSpan && cell[0].colSpan > 1) {
// If this cell has a colspan, mark it so we can reduce the colspan.
cell.addClass('tabledrag-has-colspan');
- }
- else {
+ } else {
// Mark this cell so we can hide it.
cell.addClass('tabledrag-hide');
}
@@ -328,7 +364,7 @@
* @param {bool} displayWeight
* 'true' will show weight columns.
*/
- Drupal.tableDrag.prototype.displayColumns = function (displayWeight) {
+ Drupal.tableDrag.prototype.displayColumns = function(displayWeight) {
if (displayWeight) {
this.showColumns();
}
@@ -338,7 +374,9 @@
}
// Trigger an event to allow other scripts to react to this display change.
// Force the extra parameter as a bool.
- $('table').findOnce('tabledrag').trigger('columnschange', !!displayWeight);
+ $('table')
+ .findOnce('tabledrag')
+ .trigger('columnschange', !!displayWeight);
};
/**
@@ -346,14 +384,13 @@
*
* Store only default override.
*/
- Drupal.tableDrag.prototype.toggleColumns = function () {
+ Drupal.tableDrag.prototype.toggleColumns = function() {
showWeight = !showWeight;
this.displayColumns(showWeight);
if (showWeight) {
// Save default override.
localStorage.setItem('Drupal.tableDrag.showWeight', showWeight);
- }
- else {
+ } else {
// Reset the value to its default.
localStorage.removeItem('Drupal.tableDrag.showWeight');
}
@@ -364,14 +401,14 @@
*
* Undo showColumns().
*/
- Drupal.tableDrag.prototype.hideColumns = function () {
+ Drupal.tableDrag.prototype.hideColumns = function() {
const $tables = $('table').findOnce('tabledrag');
// Hide weight/parent cells and headers.
$tables.find('.tabledrag-hide').css('display', 'none');
// Show TableDrag handles.
$tables.find('.tabledrag-handle').css('display', '');
// Reduce the colspan of any effected multi-span columns.
- $tables.find('.tabledrag-has-colspan').each(function () {
+ $tables.find('.tabledrag-has-colspan').each(function() {
this.colSpan = this.colSpan - 1;
});
// Change link text.
@@ -383,14 +420,14 @@
*
* Undo hideColumns().
*/
- Drupal.tableDrag.prototype.showColumns = function () {
+ Drupal.tableDrag.prototype.showColumns = function() {
const $tables = $('table').findOnce('tabledrag');
// Show weight/parent cells and headers.
$tables.find('.tabledrag-hide').css('display', '');
// Hide TableDrag handles.
$tables.find('.tabledrag-handle').css('display', 'none');
// Increase the colspan for any columns where it was previously reduced.
- $tables.find('.tabledrag-has-colspan').each(function () {
+ $tables.find('.tabledrag-has-colspan').each(function() {
this.colSpan = this.colSpan + 1;
});
// Change link text.
@@ -408,21 +445,23 @@
* @return {object}
* The table row settings.
*/
- Drupal.tableDrag.prototype.rowSettings = function (group, row) {
+ Drupal.tableDrag.prototype.rowSettings = function(group, row) {
const field = $(row).find(`.${group}`);
const tableSettingsGroup = this.tableSettings[group];
- return Object.keys(tableSettingsGroup).map((delta) => {
- const targetClass = tableSettingsGroup[delta].target;
- let rowSettings;
- if (field.is(`.${targetClass}`)) {
- // Return a copy of the row settings.
- rowSettings = {};
- Object.keys(tableSettingsGroup[delta]).forEach((n) => {
- rowSettings[n] = tableSettingsGroup[delta][n];
- });
- }
- return rowSettings;
- }).filter(rowSetting => rowSetting)[0];
+ return Object.keys(tableSettingsGroup)
+ .map(delta => {
+ const targetClass = tableSettingsGroup[delta].target;
+ let rowSettings;
+ if (field.is(`.${targetClass}`)) {
+ // Return a copy of the row settings.
+ rowSettings = {};
+ Object.keys(tableSettingsGroup[delta]).forEach(n => {
+ rowSettings[n] = tableSettingsGroup[delta][n];
+ });
+ }
+ return rowSettings;
+ })
+ .filter(rowSetting => rowSetting)[0];
};
/**
@@ -431,25 +470,38 @@
* @param {HTMLElement} item
* The item to add event handlers to.
*/
- Drupal.tableDrag.prototype.makeDraggable = function (item) {
+ Drupal.tableDrag.prototype.makeDraggable = function(item) {
const self = this;
const $item = $(item);
// Add a class to the title link.
- $item.find('td:first-of-type').find('a').addClass('menu-item__link');
+ $item
+ .find('td:first-of-type')
+ .find('a')
+ .addClass('menu-item__link');
// Create the handle.
- const handle = $('<a href="#" class="tabledrag-handle"><div class="handle">&nbsp;</div></a>').attr('title', Drupal.t('Drag to re-order'));
+ const handle = $(
+ '<a href="#" class="tabledrag-handle"><div class="handle">&nbsp;</div></a>',
+ ).attr('title', Drupal.t('Drag to re-order'));
// Insert the handle after indentations (if any).
- const $indentationLast = $item.find('td:first-of-type').find('.js-indentation').eq(-1);
+ const $indentationLast = $item
+ .find('td:first-of-type')
+ .find('.js-indentation')
+ .eq(-1);
if ($indentationLast.length) {
$indentationLast.after(handle);
// Update the total width of indentation in this entire table.
- self.indentCount = Math.max($item.find('.js-indentation').length, self.indentCount);
- }
- else {
- $item.find('td').eq(0).prepend(handle);
+ self.indentCount = Math.max(
+ $item.find('.js-indentation').length,
+ self.indentCount,
+ );
+ } else {
+ $item
+ .find('td')
+ .eq(0)
+ .prepend(handle);
}
- handle.on('mousedown touchstart pointerdown', (event) => {
+ handle.on('mousedown touchstart pointerdown', event => {
event.preventDefault();
if (event.originalEvent.type === 'touchstart') {
event = event.originalEvent.touches[0];
@@ -458,7 +510,7 @@
});
// Prevent the anchor tag from jumping us to the top of the page.
- handle.on('click', (e) => {
+ handle.on('click', e => {
e.preventDefault();
});
@@ -469,17 +521,23 @@
// On blur, fire the same function as a touchend/mouseup. This is used to
// update values after a row has been moved through the keyboard support.
- handle.on('blur', (event) => {
+ handle.on('blur', event => {
if (self.rowObject && self.safeBlur) {
self.dropRow(event, self);
}
});
// Add arrow-key support to the handle.
- handle.on('keydown', (event) => {
+ handle.on('keydown', event => {
// If a rowObject doesn't yet exist and this isn't the tab key.
if (event.keyCode !== 9 && !self.rowObject) {
- self.rowObject = new self.row(item, 'keyboard', self.indentEnabled, self.maxDepth, true);
+ self.rowObject = new self.row(
+ item,
+ 'keyboard',
+ self.indentEnabled,
+ self.maxDepth,
+ true,
+ );
}
let keyChange = false;
@@ -515,18 +573,25 @@
if ($(item).is('.tabledrag-root')) {
// Swap with the previous top-level row.
groupHeight = 0;
- while (previousRow && $previousRow.find('.js-indentation').length) {
+ while (
+ previousRow &&
+ $previousRow.find('.js-indentation').length
+ ) {
$previousRow = $(previousRow).prev('tr:first-of-type');
previousRow = $previousRow.get(0);
- groupHeight += $previousRow.is(':hidden') ? 0 : previousRow.offsetHeight;
+ groupHeight += $previousRow.is(':hidden')
+ ? 0
+ : previousRow.offsetHeight;
}
if (previousRow) {
self.rowObject.swap('before', previousRow);
// No need to check for indentation, 0 is the only valid one.
window.scrollBy(0, -groupHeight);
}
- }
- else if (self.table.tBodies[0].rows[0] !== previousRow || $previousRow.is('.draggable')) {
+ } else if (
+ self.table.tBodies[0].rows[0] !== previousRow ||
+ $previousRow.is('.draggable')
+ ) {
// Swap with the previous row (unless previous row is the first
// one and undraggable).
self.rowObject.swap('before', previousRow);
@@ -551,7 +616,9 @@
case 40:
// Safari down arrow.
case 63233: {
- let $nextRow = $(self.rowObject.group).eq(-1).next('tr:first-of-type');
+ let $nextRow = $(self.rowObject.group)
+ .eq(-1)
+ .next('tr:first-of-type');
let nextRow = $nextRow.get(0);
while (nextRow && $nextRow.is(':hidden')) {
$nextRow = $(nextRow).next('tr:first-of-type');
@@ -566,18 +633,25 @@
if ($(item).is('.tabledrag-root')) {
// Swap with the next group (necessarily a top-level one).
groupHeight = 0;
- const nextGroup = new self.row(nextRow, 'keyboard', self.indentEnabled, self.maxDepth, false);
+ const nextGroup = new self.row(
+ nextRow,
+ 'keyboard',
+ self.indentEnabled,
+ self.maxDepth,
+ false,
+ );
if (nextGroup) {
- $(nextGroup.group).each(function () {
+ $(nextGroup.group).each(function() {
groupHeight += $(this).is(':hidden') ? 0 : this.offsetHeight;
});
- const nextGroupRow = $(nextGroup.group).eq(-1).get(0);
+ const nextGroupRow = $(nextGroup.group)
+ .eq(-1)
+ .get(0);
self.rowObject.swap('after', nextGroupRow);
// No need to check for indentation, 0 is the only valid one.
window.scrollBy(0, parseInt(groupHeight, 10));
}
- }
- else {
+ } else {
// Swap with the next row.
self.rowObject.swap('after', nextRow);
self.rowObject.interval = null;
@@ -615,7 +689,7 @@
// scrolling. IE and Safari will suppress scrolling on keydown, but all
// other browsers need to return false on keypress.
// http://www.quirksmode.org/js/keys.html
- handle.on('keypress', (event) => {
+ handle.on('keypress', event => {
/* eslint-disable no-fallthrough */
switch (event.keyCode) {
@@ -644,7 +718,7 @@
* @param {HTMLElement} item
* The item that that is being dragged.
*/
- Drupal.tableDrag.prototype.dragStart = function (event, self, item) {
+ Drupal.tableDrag.prototype.dragStart = function(event, self, item) {
// Create a new dragObject recording the pointer information.
self.dragObject = {};
self.dragObject.initOffset = self.getPointerOffset(item, event);
@@ -655,11 +729,19 @@
// If there's a lingering row object from the keyboard, remove its focus.
if (self.rowObject) {
- $(self.rowObject.element).find('a.tabledrag-handle').trigger('blur');
+ $(self.rowObject.element)
+ .find('a.tabledrag-handle')
+ .trigger('blur');
}
// Create a new rowObject for manipulation of this row.
- self.rowObject = new self.row(item, 'pointer', self.indentEnabled, self.maxDepth, true);
+ self.rowObject = new self.row(
+ item,
+ 'pointer',
+ self.indentEnabled,
+ self.maxDepth,
+ true,
+ );
// Save the position of the table.
self.table.topY = $(self.table).offset().top;
@@ -686,7 +768,7 @@
* @return {bool|undefined}
* Undefined if no dragObject is defined, false otherwise.
*/
- Drupal.tableDrag.prototype.dragRow = function (event, self) {
+ Drupal.tableDrag.prototype.dragRow = function(event, self) {
if (self.dragObject) {
self.currentPointerCoords = self.pointerCoords(event);
const y = self.currentPointerCoords.y - self.dragObject.initOffset.y;
@@ -714,8 +796,7 @@
if (currentRow) {
if (self.rowObject.direction === 'down') {
self.rowObject.swap('after', currentRow, self);
- }
- else {
+ } else {
self.rowObject.swap('before', currentRow, self);
}
if (self.striping === true) {
@@ -726,7 +807,8 @@
// Similar to row swapping, handle indentations.
if (self.indentEnabled) {
- const xDiff = self.currentPointerCoords.x - self.dragObject.indentPointerPos.x;
+ const xDiff =
+ self.currentPointerCoords.x - self.dragObject.indentPointerPos.x;
// Set the number of indentations the pointer has been moved left or
// right.
const indentDiff = Math.round(xDiff / self.indentAmount);
@@ -734,7 +816,8 @@
// restricted according to the rows around this row.
const indentChange = self.rowObject.indent(indentDiff);
// Update table and pointer indentations.
- self.dragObject.indentPointerPos.x += self.indentAmount * indentChange * self.rtl;
+ self.dragObject.indentPointerPos.x +=
+ self.indentAmount * indentChange * self.rtl;
self.indentCount = Math.max(self.indentCount, self.rowObject.indents);
}
@@ -750,7 +833,7 @@
* @param {Drupal.tableDrag} self
* The tableDrag instance.
*/
- Drupal.tableDrag.prototype.dropRow = function (event, self) {
+ Drupal.tableDrag.prototype.dropRow = function(event, self) {
let droppedRow;
let $droppedRow;
@@ -765,10 +848,10 @@
// If a setting exists for affecting the entire group, update all the
// fields in the entire dragged group.
- Object.keys(self.tableSettings || {}).forEach((group) => {
+ Object.keys(self.tableSettings || {}).forEach(group => {
const rowSettings = self.rowSettings(group, droppedRow);
if (rowSettings.relationship === 'group') {
- Object.keys(self.rowObject.children || {}).forEach((n) => {
+ Object.keys(self.rowObject.children || {}).forEach(n => {
self.updateField(self.rowObject.children[n], group);
});
}
@@ -776,7 +859,10 @@
self.rowObject.markChanged();
if (self.changed === false) {
- $(Drupal.theme('tableDragChangedWarning')).insertBefore(self.table).hide().fadeIn('slow');
+ $(Drupal.theme('tableDragChangedWarning'))
+ .insertBefore(self.table)
+ .hide()
+ .fadeIn('slow');
self.changed = true;
}
}
@@ -810,13 +896,13 @@
* @return {object}
* An object with `x` and `y` keys indicating the position.
*/
- Drupal.tableDrag.prototype.pointerCoords = function (event) {
+ Drupal.tableDrag.prototype.pointerCoords = function(event) {
if (event.pageX || event.pageY) {
return { x: event.pageX, y: event.pageY };
}
return {
- x: (event.clientX + document.body.scrollLeft) - document.body.clientLeft,
- y: (event.clientY + document.body.scrollTop) - document.body.clientTop,
+ x: event.clientX + document.body.scrollLeft - document.body.clientLeft,
+ y: event.clientY + document.body.scrollTop - document.body.clientTop,
};
};
@@ -834,7 +920,7 @@
* @return {object}
* An object with `x` and `y` keys indicating the position.
*/
- Drupal.tableDrag.prototype.getPointerOffset = function (target, event) {
+ Drupal.tableDrag.prototype.getPointerOffset = function(target, event) {
const docPos = $(target).offset();
const pointerPos = this.pointerCoords(event);
return { x: pointerPos.x - docPos.left, y: pointerPos.y - docPos.top };
@@ -853,7 +939,7 @@
* @return {*}
* The drop target row, if found.
*/
- Drupal.tableDrag.prototype.findDropTargetRow = function (x, y) {
+ Drupal.tableDrag.prototype.findDropTargetRow = function(x, y) {
const rows = $(this.table.tBodies[0].rows).not(':hidden');
for (let n = 0; n < rows.length; n++) {
let row = rows[n];
@@ -872,11 +958,14 @@
}
// Because we always insert before, we need to offset the height a bit.
- if ((y > (rowY - rowHeight)) && (y < (rowY + rowHeight))) {
+ if (y > rowY - rowHeight && y < rowY + rowHeight) {
if (this.indentEnabled) {
// Check that this row is not a child of the row being dragged.
- if (Object.keys(this.rowObject.group)
- .some(o => (this.rowObject.group[o] === row))) {
+ if (
+ Object.keys(this.rowObject.group).some(
+ o => this.rowObject.group[o] === row,
+ )
+ ) {
return null;
}
}
@@ -909,8 +998,8 @@
* @param {HTMLElement} changedRow
* DOM object for the row that was just dropped.
*/
- Drupal.tableDrag.prototype.updateFields = function (changedRow) {
- Object.keys(this.tableSettings || {}).forEach((group) => {
+ Drupal.tableDrag.prototype.updateFields = function(changedRow) {
+ Object.keys(this.tableSettings || {}).forEach(group => {
// Each group may have a different setting for relationship, so we find
// the source rows for each separately.
this.updateField(changedRow, group);
@@ -925,7 +1014,7 @@
* @param {string} group
* The settings group on which field updates will occur.
*/
- Drupal.tableDrag.prototype.updateField = function (changedRow, group) {
+ Drupal.tableDrag.prototype.updateField = function(changedRow, group) {
let rowSettings = this.rowSettings(group, changedRow);
const $changedRow = $(changedRow);
let sourceRow;
@@ -933,7 +1022,10 @@
let previousRow;
let useSibling;
// Set the row as its own target.
- if (rowSettings.relationship === 'self' || rowSettings.relationship === 'group') {
+ if (
+ rowSettings.relationship === 'self' ||
+ rowSettings.relationship === 'group'
+ ) {
sourceRow = changedRow;
}
// Siblings are easy, check previous and next rows.
@@ -943,23 +1035,32 @@
const $nextRow = $changedRow.next('tr:first-of-type');
const nextRow = $nextRow.get(0);
sourceRow = changedRow;
- if ($previousRow.is('.draggable') && $previousRow.find(`.${group}`).length) {
+ if (
+ $previousRow.is('.draggable') &&
+ $previousRow.find(`.${group}`).length
+ ) {
if (this.indentEnabled) {
- if ($previousRow.find('.js-indentations').length === $changedRow.find('.js-indentations').length) {
+ if (
+ $previousRow.find('.js-indentations').length ===
+ $changedRow.find('.js-indentations').length
+ ) {
sourceRow = previousRow;
}
- }
- else {
+ } else {
sourceRow = previousRow;
}
- }
- else if ($nextRow.is('.draggable') && $nextRow.find(`.${group}`).length) {
+ } else if (
+ $nextRow.is('.draggable') &&
+ $nextRow.find(`.${group}`).length
+ ) {
if (this.indentEnabled) {
- if ($nextRow.find('.js-indentations').length === $changedRow.find('.js-indentations').length) {
+ if (
+ $nextRow.find('.js-indentations').length ===
+ $changedRow.find('.js-indentations').length
+ ) {
sourceRow = nextRow;
}
- }
- else {
+ } else {
sourceRow = nextRow;
}
}
@@ -969,7 +1070,10 @@
else if (rowSettings.relationship === 'parent') {
$previousRow = $changedRow.prev('tr');
previousRow = $previousRow;
- while ($previousRow.length && $previousRow.find('.js-indentation').length >= this.rowObject.indents) {
+ while (
+ $previousRow.length &&
+ $previousRow.find('.js-indentation').length >= this.rowObject.indents
+ ) {
$previousRow = $previousRow.prev('tr');
previousRow = $previousRow;
}
@@ -983,9 +1087,13 @@
// Use the first row in the table as source, because it's guaranteed to
// be at the root level. Find the first item, then compare this row
// against it as a sibling.
- sourceRow = $(this.table).find('tr.draggable:first-of-type').get(0);
+ sourceRow = $(this.table)
+ .find('tr.draggable:first-of-type')
+ .get(0);
if (sourceRow === this.rowObject.element) {
- sourceRow = $(this.rowObject.group[this.rowObject.group.length - 1]).next('tr.draggable').get(0);
+ sourceRow = $(this.rowObject.group[this.rowObject.group.length - 1])
+ .next('tr.draggable')
+ .get(0);
}
useSibling = true;
}
@@ -1013,7 +1121,9 @@
switch (rowSettings.action) {
case 'depth':
// Get the depth of the target row.
- targetElement.value = $(sourceElement).closest('tr').find('.js-indentation').length;
+ targetElement.value = $(sourceElement)
+ .closest('tr')
+ .find('.js-indentation').length;
break;
case 'match':
@@ -1026,29 +1136,39 @@
if ($(targetElement).is('select')) {
// Get a list of acceptable values.
const values = [];
- $(targetElement).find('option').each(function () {
- values.push(this.value);
- });
+ $(targetElement)
+ .find('option')
+ .each(function() {
+ values.push(this.value);
+ });
const maxVal = values[values.length - 1];
// Populate the values in the siblings.
- $(siblings).find(targetClass).each(function () {
- // If there are more items than possible values, assign the
- // maximum value to the row.
- if (values.length > 0) {
- this.value = values.shift();
- }
- else {
- this.value = maxVal;
- }
- });
- }
- else {
+ $(siblings)
+ .find(targetClass)
+ .each(function() {
+ // If there are more items than possible values, assign the
+ // maximum value to the row.
+ if (values.length > 0) {
+ this.value = values.shift();
+ } else {
+ this.value = maxVal;
+ }
+ });
+ } else {
// Assume a numeric input field.
- let weight = parseInt($(siblings[0]).find(targetClass).val(), 10) || 0;
- $(siblings).find(targetClass).each(function () {
- this.value = weight;
- weight++;
- });
+ let weight =
+ parseInt(
+ $(siblings[0])
+ .find(targetClass)
+ .val(),
+ 10,
+ ) || 0;
+ $(siblings)
+ .find(targetClass)
+ .each(function() {
+ this.value = weight;
+ weight++;
+ });
}
break;
}
@@ -1070,7 +1190,11 @@
* @param {string} group
* The group selector.
*/
- Drupal.tableDrag.prototype.copyDragClasses = function (sourceRow, targetRow, group) {
+ Drupal.tableDrag.prototype.copyDragClasses = function(
+ sourceRow,
+ targetRow,
+ group,
+ ) {
const sourceElement = $(sourceRow).find(`.${group}`);
const targetElement = $(targetRow).find(`.${group}`);
if (sourceElement.length && targetElement.length) {
@@ -1087,17 +1211,20 @@
* @return {number}
* The suggested scroll.
*/
- Drupal.tableDrag.prototype.checkScroll = function (cursorY) {
+ Drupal.tableDrag.prototype.checkScroll = function(cursorY) {
const de = document.documentElement;
const b = document.body;
- const windowHeight = window.innerHeight || (de.clientHeight && de.clientWidth !== 0 ? de.clientHeight : b.offsetHeight);
+ const windowHeight =
+ window.innerHeight ||
+ (de.clientHeight && de.clientWidth !== 0
+ ? de.clientHeight
+ : b.offsetHeight);
this.windowHeight = windowHeight;
let scrollY;
if (document.all) {
scrollY = !de.scrollTop ? b.scrollTop : de.scrollTop;
- }
- else {
+ } else {
scrollY = window.pageYOffset ? window.pageYOffset : window.scrollY;
}
this.scrollY = scrollY;
@@ -1106,13 +1233,13 @@
// Return a scroll speed relative to the edge of the screen.
if (cursorY - scrollY > windowHeight - trigger) {
- delta = trigger / ((windowHeight + scrollY) - cursorY);
- delta = (delta > 0 && delta < trigger) ? delta : trigger;
+ delta = trigger / (windowHeight + scrollY - cursorY);
+ delta = delta > 0 && delta < trigger ? delta : trigger;
return delta * this.scrollSettings.amount;
}
if (cursorY - scrollY < trigger) {
delta = trigger / (cursorY - scrollY);
- delta = (delta > 0 && delta < trigger) ? delta : trigger;
+ delta = delta > 0 && delta < trigger ? delta : trigger;
return -delta * this.scrollSettings.amount;
}
};
@@ -1123,7 +1250,7 @@
* @param {number} scrollAmount
* The amount of scroll to apply to the window.
*/
- Drupal.tableDrag.prototype.setScroll = function (scrollAmount) {
+ Drupal.tableDrag.prototype.setScroll = function(scrollAmount) {
const self = this;
this.scrollInterval = setInterval(() => {
@@ -1143,7 +1270,7 @@
/**
* Command to restripe table properly.
*/
- Drupal.tableDrag.prototype.restripeTable = function () {
+ Drupal.tableDrag.prototype.restripeTable = function() {
// :even and :odd are reversed because jQuery counts from 0 and
// we count from 1, so we're out of sync.
// Match immediate children of the parent element to allow nesting.
@@ -1165,7 +1292,7 @@
* @return {null}
* Returns null when the stub function is used.
*/
- Drupal.tableDrag.prototype.onDrag = function () {
+ Drupal.tableDrag.prototype.onDrag = function() {
return null;
};
@@ -1175,7 +1302,7 @@
* @return {null}
* Returns null when the stub function is used.
*/
- Drupal.tableDrag.prototype.onDrop = function () {
+ Drupal.tableDrag.prototype.onDrop = function() {
return null;
};
@@ -1195,7 +1322,13 @@
* Whether we want to add classes to this row to indicate child
* relationships.
*/
- Drupal.tableDrag.prototype.row = function (tableRow, method, indentEnabled, maxDepth, addClasses) {
+ Drupal.tableDrag.prototype.row = function(
+ tableRow,
+ method,
+ indentEnabled,
+ maxDepth,
+ addClasses,
+ ) {
const $tableRow = $(tableRow);
this.element = tableRow;
@@ -1214,7 +1347,10 @@
this.group = $.merge(this.group, this.children);
// Find the depth of this entire group.
for (let n = 0; n < this.group.length; n++) {
- this.groupDepth = Math.max($(this.group[n]).find('.js-indentation').length, this.groupDepth);
+ this.groupDepth = Math.max(
+ $(this.group[n]).find('.js-indentation').length,
+ this.groupDepth,
+ );
}
}
};
@@ -1229,7 +1365,7 @@
* @return {Array}
* An array of children of the row.
*/
- Drupal.tableDrag.prototype.row.prototype.findChildren = function (addClasses) {
+ Drupal.tableDrag.prototype.row.prototype.findChildren = function(addClasses) {
const parentIndentation = this.indents;
let currentRow = $(this.element, this.table).next('tr.draggable');
const rows = [];
@@ -1237,13 +1373,12 @@
function rowIndentation(indentNum, el) {
const self = $(el);
- if (child === 1 && (indentNum === parentIndentation)) {
+ if (child === 1 && indentNum === parentIndentation) {
self.addClass('tree-child-first');
}
if (indentNum === parentIndentation) {
self.addClass('tree-child');
- }
- else if (indentNum > parentIndentation) {
+ } else if (indentNum > parentIndentation) {
self.addClass('tree-child-horizontal');
}
}
@@ -1256,14 +1391,15 @@
if (addClasses) {
currentRow.find('.js-indentation').each(rowIndentation);
}
- }
- else {
+ } else {
break;
}
currentRow = currentRow.next('tr.draggable');
}
if (addClasses && rows.length) {
- $(rows[rows.length - 1]).find(`.js-indentation:nth-child(${parentIndentation + 1})`).addClass('tree-child-last');
+ $(rows[rows.length - 1])
+ .find(`.js-indentation:nth-child(${parentIndentation + 1})`)
+ .addClass('tree-child-last');
}
return rows;
};
@@ -1277,7 +1413,7 @@
* @return {bool}
* Whether the swap is a valid swap or not.
*/
- Drupal.tableDrag.prototype.row.prototype.isValidSwap = function (row) {
+ Drupal.tableDrag.prototype.row.prototype.isValidSwap = function(row) {
const $row = $(row);
if (this.indentEnabled) {
let prevRow;
@@ -1285,8 +1421,7 @@
if (this.direction === 'down') {
prevRow = row;
nextRow = $row.next('tr').get(0);
- }
- else {
+ } else {
prevRow = $row.prev('tr').get(0);
nextRow = row;
}
@@ -1314,14 +1449,14 @@
* @param {HTMLElement} row
* DOM element what will be swapped with the row group.
*/
- Drupal.tableDrag.prototype.row.prototype.swap = function (position, row) {
+ Drupal.tableDrag.prototype.row.prototype.swap = function(position, row) {
// Makes sure only DOM object are passed to Drupal.detachBehaviors().
- this.group.forEach((row) => {
+ this.group.forEach(row => {
Drupal.detachBehaviors(row, drupalSettings, 'move');
});
$(row)[position](this.group);
// Makes sure only DOM object are passed to Drupal.attachBehaviors()s.
- this.group.forEach((row) => {
+ this.group.forEach(row => {
Drupal.attachBehaviors(row, drupalSettings);
});
this.changed = true;
@@ -1342,7 +1477,10 @@
* An object with the keys `min` and `max` to indicate the valid indent
* interval.
*/
- Drupal.tableDrag.prototype.row.prototype.validIndentInterval = function (prevRow, nextRow) {
+ Drupal.tableDrag.prototype.row.prototype.validIndentInterval = function(
+ prevRow,
+ nextRow,
+ ) {
const $prevRow = $(prevRow);
let maxIndent;
@@ -1351,19 +1489,27 @@
const minIndent = nextRow ? $(nextRow).find('.js-indentation').length : 0;
// Maximum indentation:
- if (!prevRow || $prevRow.is(':not(.draggable)') || $(this.element).is('.tabledrag-root')) {
+ if (
+ !prevRow ||
+ $prevRow.is(':not(.draggable)') ||
+ $(this.element).is('.tabledrag-root')
+ ) {
// Do not indent:
// - the first row in the table,
// - rows dragged below a non-draggable row,
// - 'root' rows.
maxIndent = 0;
- }
- else {
+ } else {
// Do not go deeper than as a child of the previous row.
- maxIndent = $prevRow.find('.js-indentation').length + ($prevRow.is('.tabledrag-leaf') ? 0 : 1);
+ maxIndent =
+ $prevRow.find('.js-indentation').length +
+ ($prevRow.is('.tabledrag-leaf') ? 0 : 1);
// Limit by the maximum allowed depth for the table.
if (this.maxDepth) {
- maxIndent = Math.min(maxIndent, this.maxDepth - (this.groupDepth - this.indents));
+ maxIndent = Math.min(
+ maxIndent,
+ this.maxDepth - (this.groupDepth - this.indents),
+ );
}
}
@@ -1381,12 +1527,17 @@
* @return {number}
* The number of indentations applied.
*/
- Drupal.tableDrag.prototype.row.prototype.indent = function (indentDiff) {
+ Drupal.tableDrag.prototype.row.prototype.indent = function(indentDiff) {
const $group = $(this.group);
// Determine the valid indentations interval if not available yet.
if (!this.interval) {
- const prevRow = $(this.element).prev('tr').get(0);
- const nextRow = $group.eq(-1).next('tr').get(0);
+ const prevRow = $(this.element)
+ .prev('tr')
+ .get(0);
+ const nextRow = $group
+ .eq(-1)
+ .next('tr')
+ .get(0);
this.interval = this.validIndentInterval(prevRow, nextRow);
}
@@ -1401,9 +1552,10 @@
if (indentDiff < 0) {
$group.find('.js-indentation:first-of-type').remove();
this.indents--;
- }
- else {
- $group.find('td:first-of-type').prepend(Drupal.theme('tableDragIndentation'));
+ } else {
+ $group
+ .find('td:first-of-type')
+ .prepend(Drupal.theme('tableDragIndentation'));
this.indents++;
}
}
@@ -1429,7 +1581,9 @@
* @return {Array}
* An array of siblings.
*/
- Drupal.tableDrag.prototype.row.prototype.findSiblings = function (rowSettings) {
+ Drupal.tableDrag.prototype.row.prototype.findSiblings = function(
+ rowSettings,
+ ) {
const siblings = [];
const directions = ['prev', 'next'];
const rowIndentation = this.indents;
@@ -1445,15 +1599,13 @@
checkRowIndentation = checkRow.find('.js-indentation').length;
}
- if (!(this.indentEnabled) || (checkRowIndentation === rowIndentation)) {
+ if (!this.indentEnabled || checkRowIndentation === rowIndentation) {
siblings.push(checkRow[0]);
- }
- else if (checkRowIndentation < rowIndentation) {
+ } else if (checkRowIndentation < rowIndentation) {
// No need to keep looking for siblings when we get to a parent.
break;
}
- }
- else {
+ } else {
break;
}
checkRow = checkRow[directions[d]]();
@@ -1471,9 +1623,10 @@
/**
* Remove indentation helper classes from the current row group.
*/
- Drupal.tableDrag.prototype.row.prototype.removeIndentClasses = function () {
- Object.keys(this.children || {}).forEach((n) => {
- $(this.children[n]).find('.js-indentation')
+ Drupal.tableDrag.prototype.row.prototype.removeIndentClasses = function() {
+ Object.keys(this.children || {}).forEach(n => {
+ $(this.children[n])
+ .find('.js-indentation')
.removeClass('tree-child')
.removeClass('tree-child-first')
.removeClass('tree-child-last')
@@ -1484,7 +1637,7 @@
/**
* Add an asterisk or other marker to the changed row.
*/
- Drupal.tableDrag.prototype.row.prototype.markChanged = function () {
+ Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
const marker = Drupal.theme('tableDragChangedMarker');
const cell = $(this.element).find('td:first-of-type');
if (cell.find('abbr.tabledrag-changed').length === 0) {
@@ -1498,7 +1651,7 @@
* @return {null}
* Returns null when the stub function is used.
*/
- Drupal.tableDrag.prototype.row.prototype.onIndent = function () {
+ Drupal.tableDrag.prototype.row.prototype.onIndent = function() {
return null;
};
@@ -1511,34 +1664,40 @@
* @return {null}
* Returns null when the stub function is used.
*/
- Drupal.tableDrag.prototype.row.prototype.onSwap = function (swappedRow) {
+ Drupal.tableDrag.prototype.row.prototype.onSwap = function(swappedRow) {
return null;
};
- $.extend(Drupal.theme, /** @lends Drupal.theme */{
-
- /**
- * @return {string}
- * Markup for the marker.
- */
- tableDragChangedMarker() {
- return `<abbr class="warning tabledrag-changed" title="${Drupal.t('Changed')}">*</abbr>`;
- },
+ $.extend(
+ Drupal.theme,
+ /** @lends Drupal.theme */ {
+ /**
+ * @return {string}
+ * Markup for the marker.
+ */
+ tableDragChangedMarker() {
+ return `<abbr class="warning tabledrag-changed" title="${Drupal.t(
+ 'Changed',
+ )}">*</abbr>`;
+ },
- /**
- * @return {string}
- * Markup for the indentation.
- */
- tableDragIndentation() {
- return '<div class="js-indentation indentation">&nbsp;</div>';
- },
+ /**
+ * @return {string}
+ * Markup for the indentation.
+ */
+ tableDragIndentation() {
+ return '<div class="js-indentation indentation">&nbsp;</div>';
+ },
- /**
- * @return {string}
- * Markup for the warning.
- */
- tableDragChangedWarning() {
- return `<div class="tabledrag-changed-warning messages messages--warning" role="alert">${Drupal.theme('tableDragChangedMarker')} ${Drupal.t('You have unsaved changes.')}</div>`;
+ /**
+ * @return {string}
+ * Markup for the warning.
+ */
+ tableDragChangedWarning() {
+ return `<div class="tabledrag-changed-warning messages messages--warning" role="alert">${Drupal.theme(
+ 'tableDragChangedMarker',
+ )} ${Drupal.t('You have unsaved changes.')}</div>`;
+ },
},
- });
-}(jQuery, Drupal, drupalSettings));
+ );
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/misc/tableheader.es6.js b/core/misc/tableheader.es6.js
index 289e3fc..9e26be5 100644
--- a/core/misc/tableheader.es6.js
+++ b/core/misc/tableheader.es6.js
@@ -3,7 +3,7 @@
* Sticky table headers.
*/
-(function ($, Drupal, displace) {
+(function($, Drupal, displace) {
/**
* Constructor for the tableHeader object. Provides sticky table headers.
*
@@ -46,13 +46,20 @@
this.tableOffset = this.$originalTable.offset();
// React to columns change to avoid making checks in the scroll callback.
- this.$originalTable.on('columnschange', { tableHeader: this }, (e, display) => {
- const tableHeader = e.data.tableHeader;
- if (tableHeader.displayWeight === null || tableHeader.displayWeight !== display) {
- tableHeader.recalculateSticky();
- }
- tableHeader.displayWeight = display;
- });
+ this.$originalTable.on(
+ 'columnschange',
+ { tableHeader: this },
+ (e, display) => {
+ const tableHeader = e.data.tableHeader;
+ if (
+ tableHeader.displayWeight === null ||
+ tableHeader.displayWeight !== display
+ ) {
+ tableHeader.recalculateSticky();
+ }
+ tableHeader.displayWeight = display;
+ },
+ );
// Create and display sticky header.
this.createSticky();
@@ -69,7 +76,9 @@
// Select and initialize sticky table headers.
function tableHeaderInitHandler(e) {
- const $tables = $(e.data.context).find('table.sticky-enabled').once('tableheader');
+ const $tables = $(e.data.context)
+ .find('table.sticky-enabled')
+ .once('tableheader');
const il = $tables.length;
for (let i = 0; i < il; i++) {
TableHeader.tables.push(new TableHeader($tables[i]));
@@ -87,7 +96,11 @@
*/
Drupal.behaviors.tableHeader = {
attach(context) {
- $(window).one('scroll.TableHeaderInit', { context }, tableHeaderInitHandler);
+ $(window).one(
+ 'scroll.TableHeaderInit',
+ { context },
+ tableHeaderInitHandler,
+ );
},
};
@@ -109,7 +122,6 @@
// Bind event that need to change all tables.
$(window).on({
-
/**
* When resizing table width can change, recalculate everything.
*
@@ -126,7 +138,6 @@
});
// Bind to custom Drupal events.
$(document).on({
-
/**
* Recalculate columns width when window is resized and when show/hide
* weight is triggered.
@@ -146,167 +157,173 @@
/**
* Store the state of TableHeader.
*/
- $.extend(TableHeader, /** @lends Drupal.TableHeader */{
-
- /**
- * This will store the state of all processed tables.
- *
- * @type {Array.<Drupal.TableHeader>}
- */
- tables: [],
- });
+ $.extend(
+ TableHeader,
+ /** @lends Drupal.TableHeader */ {
+ /**
+ * This will store the state of all processed tables.
+ *
+ * @type {Array.<Drupal.TableHeader>}
+ */
+ tables: [],
+ },
+ );
/**
* Extend TableHeader prototype.
*/
- $.extend(TableHeader.prototype, /** @lends Drupal.TableHeader# */{
-
- /**
- * Minimum height in pixels for the table to have a sticky header.
- *
- * @type {number}
- */
- minHeight: 100,
-
- /**
- * Absolute position of the table on the page.
- *
- * @type {?Drupal~displaceOffset}
- */
- tableOffset: null,
-
- /**
- * Absolute position of the table on the page.
- *
- * @type {?number}
- */
- tableHeight: null,
-
- /**
- * Boolean storing the sticky header visibility state.
- *
- * @type {bool}
- */
- stickyVisible: false,
-
- /**
- * Create the duplicate header.
- */
- createSticky() {
- // Clone the table header so it inherits original jQuery properties.
- const $stickyHeader = this.$originalHeader.clone(true);
- // Hide the table to avoid a flash of the header clone upon page load.
- this.$stickyTable = $('<table class="sticky-header"/>')
- .css({
- visibility: 'hidden',
- position: 'fixed',
- top: '0px',
- })
- .append($stickyHeader)
- .insertBefore(this.$originalTable);
-
- this.$stickyHeaderCells = $stickyHeader.find('> tr > th');
-
- // Initialize all computations.
- this.recalculateSticky();
- },
-
- /**
- * Set absolute position of sticky.
- *
- * @param {number} offsetTop
- * The top offset for the sticky header.
- * @param {number} offsetLeft
- * The left offset for the sticky header.
- *
- * @return {jQuery}
- * The sticky table as a jQuery collection.
- */
- stickyPosition(offsetTop, offsetLeft) {
- const css = {};
- if (typeof offsetTop === 'number') {
- css.top = `${offsetTop}px`;
- }
- if (typeof offsetLeft === 'number') {
- css.left = `${this.tableOffset.left - offsetLeft}px`;
- }
- return this.$stickyTable.css(css);
- },
-
- /**
- * Returns true if sticky is currently visible.
- *
- * @return {bool}
- * The visibility status.
- */
- checkStickyVisible() {
- const scrollTop = scrollValue('scrollTop');
- const tableTop = this.tableOffset.top - displace.offsets.top;
- const tableBottom = tableTop + this.tableHeight;
- let visible = false;
-
- if (tableTop < scrollTop && scrollTop < (tableBottom - this.minHeight)) {
- visible = true;
- }
-
- this.stickyVisible = visible;
- return visible;
- },
-
- /**
- * Check if sticky header should be displayed.
- *
- * This function is throttled to once every 250ms to avoid unnecessary
- * calls.
- *
- * @param {jQuery.Event} e
- * The scroll event.
- */
- onScroll(e) {
- this.checkStickyVisible();
- // Track horizontal positioning relative to the viewport.
- this.stickyPosition(null, scrollValue('scrollLeft'));
- this.$stickyTable.css('visibility', this.stickyVisible ? 'visible' : 'hidden');
- },
-
- /**
- * Event handler: recalculates position of the sticky table header.
- *
- * @param {jQuery.Event} event
- * Event being triggered.
- */
- recalculateSticky(event) {
- // Update table size.
- this.tableHeight = this.$originalTable[0].clientHeight;
-
- // Update offset top.
- displace.offsets.top = displace.calculateOffset('top');
- this.tableOffset = this.$originalTable.offset();
- this.stickyPosition(displace.offsets.top, scrollValue('scrollLeft'));
-
- // Update columns width.
- let $that = null;
- let $stickyCell = null;
- let display = null;
- // Resize header and its cell widths.
- // Only apply width to visible table cells. This prevents the header from
- // displaying incorrectly when the sticky header is no longer visible.
- const il = this.$originalHeaderCells.length;
- for (let i = 0; i < il; i++) {
- $that = $(this.$originalHeaderCells[i]);
- $stickyCell = this.$stickyHeaderCells.eq($that.index());
- display = $that.css('display');
- if (display !== 'none') {
- $stickyCell.css({ width: $that.css('width'), display });
+ $.extend(
+ TableHeader.prototype,
+ /** @lends Drupal.TableHeader# */ {
+ /**
+ * Minimum height in pixels for the table to have a sticky header.
+ *
+ * @type {number}
+ */
+ minHeight: 100,
+
+ /**
+ * Absolute position of the table on the page.
+ *
+ * @type {?Drupal~displaceOffset}
+ */
+ tableOffset: null,
+
+ /**
+ * Absolute position of the table on the page.
+ *
+ * @type {?number}
+ */
+ tableHeight: null,
+
+ /**
+ * Boolean storing the sticky header visibility state.
+ *
+ * @type {bool}
+ */
+ stickyVisible: false,
+
+ /**
+ * Create the duplicate header.
+ */
+ createSticky() {
+ // Clone the table header so it inherits original jQuery properties.
+ const $stickyHeader = this.$originalHeader.clone(true);
+ // Hide the table to avoid a flash of the header clone upon page load.
+ this.$stickyTable = $('<table class="sticky-header"/>')
+ .css({
+ visibility: 'hidden',
+ position: 'fixed',
+ top: '0px',
+ })
+ .append($stickyHeader)
+ .insertBefore(this.$originalTable);
+
+ this.$stickyHeaderCells = $stickyHeader.find('> tr > th');
+
+ // Initialize all computations.
+ this.recalculateSticky();
+ },
+
+ /**
+ * Set absolute position of sticky.
+ *
+ * @param {number} offsetTop
+ * The top offset for the sticky header.
+ * @param {number} offsetLeft
+ * The left offset for the sticky header.
+ *
+ * @return {jQuery}
+ * The sticky table as a jQuery collection.
+ */
+ stickyPosition(offsetTop, offsetLeft) {
+ const css = {};
+ if (typeof offsetTop === 'number') {
+ css.top = `${offsetTop}px`;
+ }
+ if (typeof offsetLeft === 'number') {
+ css.left = `${this.tableOffset.left - offsetLeft}px`;
}
- else {
- $stickyCell.css('display', 'none');
+ return this.$stickyTable.css(css);
+ },
+
+ /**
+ * Returns true if sticky is currently visible.
+ *
+ * @return {bool}
+ * The visibility status.
+ */
+ checkStickyVisible() {
+ const scrollTop = scrollValue('scrollTop');
+ const tableTop = this.tableOffset.top - displace.offsets.top;
+ const tableBottom = tableTop + this.tableHeight;
+ let visible = false;
+
+ if (tableTop < scrollTop && scrollTop < tableBottom - this.minHeight) {
+ visible = true;
}
- }
- this.$stickyTable.css('width', this.$originalTable.outerWidth());
+
+ this.stickyVisible = visible;
+ return visible;
+ },
+
+ /**
+ * Check if sticky header should be displayed.
+ *
+ * This function is throttled to once every 250ms to avoid unnecessary
+ * calls.
+ *
+ * @param {jQuery.Event} e
+ * The scroll event.
+ */
+ onScroll(e) {
+ this.checkStickyVisible();
+ // Track horizontal positioning relative to the viewport.
+ this.stickyPosition(null, scrollValue('scrollLeft'));
+ this.$stickyTable.css(
+ 'visibility',
+ this.stickyVisible ? 'visible' : 'hidden',
+ );
+ },
+
+ /**
+ * Event handler: recalculates position of the sticky table header.
+ *
+ * @param {jQuery.Event} event
+ * Event being triggered.
+ */
+ recalculateSticky(event) {
+ // Update table size.
+ this.tableHeight = this.$originalTable[0].clientHeight;
+
+ // Update offset top.
+ displace.offsets.top = displace.calculateOffset('top');
+ this.tableOffset = this.$originalTable.offset();
+ this.stickyPosition(displace.offsets.top, scrollValue('scrollLeft'));
+
+ // Update columns width.
+ let $that = null;
+ let $stickyCell = null;
+ let display = null;
+ // Resize header and its cell widths.
+ // Only apply width to visible table cells. This prevents the header from
+ // displaying incorrectly when the sticky header is no longer visible.
+ const il = this.$originalHeaderCells.length;
+ for (let i = 0; i < il; i++) {
+ $that = $(this.$originalHeaderCells[i]);
+ $stickyCell = this.$stickyHeaderCells.eq($that.index());
+ display = $that.css('display');
+ if (display !== 'none') {
+ $stickyCell.css({ width: $that.css('width'), display });
+ } else {
+ $stickyCell.css('display', 'none');
+ }
+ }
+ this.$stickyTable.css('width', this.$originalTable.outerWidth());
+ },
},
- });
+ );
// Expose constructor in the public space.
Drupal.TableHeader = TableHeader;
-}(jQuery, Drupal, window.parent.Drupal.displace));
+})(jQuery, Drupal, window.parent.Drupal.displace);
diff --git a/core/misc/tableresponsive.es6.js b/core/misc/tableresponsive.es6.js
index 6030b6e..c55c0f5 100644
--- a/core/misc/tableresponsive.es6.js
+++ b/core/misc/tableresponsive.es6.js
@@ -3,7 +3,7 @@
* Responsive table functionality.
*/
-(function ($, Drupal, window) {
+(function($, Drupal, window) {
/**
* The TableResponsive object optimizes table presentation for screen size.
*
@@ -28,15 +28,29 @@
// traversed only once to find them.
this.$headers = this.$table.find('th');
// Add a link before the table for users to show or hide weight columns.
- this.$link = $('<button type="button" class="link tableresponsive-toggle"></button>')
- .attr('title', Drupal.t('Show table cells that were hidden to make the table fit within a small screen.'))
+ this.$link = $(
+ '<button type="button" class="link tableresponsive-toggle"></button>',
+ )
+ .attr(
+ 'title',
+ Drupal.t(
+ 'Show table cells that were hidden to make the table fit within a small screen.',
+ ),
+ )
.on('click', $.proxy(this, 'eventhandlerToggleColumns'));
- this.$table.before($('<div class="tableresponsive-toggle-columns"></div>').append(this.$link));
+ this.$table.before(
+ $('<div class="tableresponsive-toggle-columns"></div>').append(
+ this.$link,
+ ),
+ );
// Attach a resize handler to the window.
$(window)
- .on('resize.tableresponsive', $.proxy(this, 'eventhandlerEvaluateColumnVisibility'))
+ .on(
+ 'resize.tableresponsive',
+ $.proxy(this, 'eventhandlerEvaluateColumnVisibility'),
+ )
.trigger('resize.tableresponsive');
}
@@ -50,7 +64,9 @@
*/
Drupal.behaviors.tableResponsive = {
attach(context, settings) {
- const $tables = $(context).find('table.responsive-enabled').once('tableresponsive');
+ const $tables = $(context)
+ .find('table.responsive-enabled')
+ .once('tableresponsive');
if ($tables.length) {
const il = $tables.length;
for (let i = 0; i < il; i++) {
@@ -63,15 +79,17 @@
/**
* Extend the TableResponsive function with a list of managed tables.
*/
- $.extend(TableResponsive, /** @lends Drupal.TableResponsive */{
-
- /**
- * Store all created instances.
- *
- * @type {Array.<Drupal.TableResponsive>}
- */
- tables: [],
- });
+ $.extend(
+ TableResponsive,
+ /** @lends Drupal.TableResponsive */ {
+ /**
+ * Store all created instances.
+ *
+ * @type {Array.<Drupal.TableResponsive>}
+ */
+ tables: [],
+ },
+ );
/**
* Associates an action link with the table that will show hidden columns.
@@ -79,92 +97,104 @@
* Columns are assumed to be hidden if their header has the class priority-low
* or priority-medium.
*/
- $.extend(TableResponsive.prototype, /** @lends Drupal.TableResponsive# */{
-
- /**
- * @param {jQuery.Event} e
- * The event triggered.
- */
- eventhandlerEvaluateColumnVisibility(e) {
- const pegged = parseInt(this.$link.data('pegged'), 10);
- const hiddenLength = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden').length;
- // If the table has hidden columns, associate an action link with the
- // table to show the columns.
- if (hiddenLength > 0) {
- this.$link.show().text(this.showText);
- }
- // When the toggle is pegged, its presence is maintained because the user
- // has interacted with it. This is necessary to keep the link visible if
- // the user adjusts screen size and changes the visibility of columns.
- if (!pegged && hiddenLength === 0) {
- this.$link.hide().text(this.hideText);
- }
- },
+ $.extend(
+ TableResponsive.prototype,
+ /** @lends Drupal.TableResponsive# */ {
+ /**
+ * @param {jQuery.Event} e
+ * The event triggered.
+ */
+ eventhandlerEvaluateColumnVisibility(e) {
+ const pegged = parseInt(this.$link.data('pegged'), 10);
+ const hiddenLength = this.$headers.filter(
+ '.priority-medium:hidden, .priority-low:hidden',
+ ).length;
+ // If the table has hidden columns, associate an action link with the
+ // table to show the columns.
+ if (hiddenLength > 0) {
+ this.$link.show().text(this.showText);
+ }
+ // When the toggle is pegged, its presence is maintained because the user
+ // has interacted with it. This is necessary to keep the link visible if
+ // the user adjusts screen size and changes the visibility of columns.
+ if (!pegged && hiddenLength === 0) {
+ this.$link.hide().text(this.hideText);
+ }
+ },
- /**
- * Toggle the visibility of columns based on their priority.
- *
- * Columns are classed with either 'priority-low' or 'priority-medium'.
- *
- * @param {jQuery.Event} e
- * The event triggered.
- */
- eventhandlerToggleColumns(e) {
- e.preventDefault();
- const self = this;
- const $hiddenHeaders = this.$headers.filter('.priority-medium:hidden, .priority-low:hidden');
- this.$revealedCells = this.$revealedCells || $();
- // Reveal hidden columns.
- if ($hiddenHeaders.length > 0) {
- $hiddenHeaders.each(function (index, element) {
- const $header = $(this);
- const position = $header.prevAll('th').length;
- self.$table.find('tbody tr').each(function () {
- const $cells = $(this).find('td').eq(position);
- $cells.show();
- // Keep track of the revealed cells, so they can be hidden later.
- self.$revealedCells = $().add(self.$revealedCells).add($cells);
+ /**
+ * Toggle the visibility of columns based on their priority.
+ *
+ * Columns are classed with either 'priority-low' or 'priority-medium'.
+ *
+ * @param {jQuery.Event} e
+ * The event triggered.
+ */
+ eventhandlerToggleColumns(e) {
+ e.preventDefault();
+ const self = this;
+ const $hiddenHeaders = this.$headers.filter(
+ '.priority-medium:hidden, .priority-low:hidden',
+ );
+ this.$revealedCells = this.$revealedCells || $();
+ // Reveal hidden columns.
+ if ($hiddenHeaders.length > 0) {
+ $hiddenHeaders.each(function(index, element) {
+ const $header = $(this);
+ const position = $header.prevAll('th').length;
+ self.$table.find('tbody tr').each(function() {
+ const $cells = $(this)
+ .find('td')
+ .eq(position);
+ $cells.show();
+ // Keep track of the revealed cells, so they can be hidden later.
+ self.$revealedCells = $()
+ .add(self.$revealedCells)
+ .add($cells);
+ });
+ $header.show();
+ // Keep track of the revealed headers, so they can be hidden later.
+ self.$revealedCells = $()
+ .add(self.$revealedCells)
+ .add($header);
});
- $header.show();
- // Keep track of the revealed headers, so they can be hidden later.
- self.$revealedCells = $().add(self.$revealedCells).add($header);
- });
- this.$link.text(this.hideText).data('pegged', 1);
- }
- // Hide revealed columns.
- else {
- this.$revealedCells.hide();
- // Strip the 'display:none' declaration from the style attributes of
- // the table cells that .hide() added.
- this.$revealedCells.each(function (index, element) {
- const $cell = $(this);
- const properties = $cell.attr('style').split(';');
- const newProps = [];
- // The hide method adds display none to the element. The element
- // should be returned to the same state it was in before the columns
- // were revealed, so it is necessary to remove the display none value
- // from the style attribute.
- const match = /^display\s*:\s*none$/;
- for (let i = 0; i < properties.length; i++) {
- const prop = properties[i];
- prop.trim();
- // Find the display:none property and remove it.
- const isDisplayNone = match.exec(prop);
- if (isDisplayNone) {
- continue;
+ this.$link.text(this.hideText).data('pegged', 1);
+ }
+ // Hide revealed columns.
+ else {
+ this.$revealedCells.hide();
+ // Strip the 'display:none' declaration from the style attributes of
+ // the table cells that .hide() added.
+ this.$revealedCells.each(function(index, element) {
+ const $cell = $(this);
+ const properties = $cell.attr('style').split(';');
+ const newProps = [];
+ // The hide method adds display none to the element. The element
+ // should be returned to the same state it was in before the columns
+ // were revealed, so it is necessary to remove the display none value
+ // from the style attribute.
+ const match = /^display\s*:\s*none$/;
+ for (let i = 0; i < properties.length; i++) {
+ const prop = properties[i];
+ prop.trim();
+ // Find the display:none property and remove it.
+ const isDisplayNone = match.exec(prop);
+ if (isDisplayNone) {
+ continue;
+ }
+ newProps.push(prop);
}
- newProps.push(prop);
- }
- // Return the rest of the style attribute values to the element.
- $cell.attr('style', newProps.join(';'));
- });
- this.$link.text(this.showText).data('pegged', 0);
- // Refresh the toggle link.
- $(window).trigger('resize.tableresponsive');
- }
+ // Return the rest of the style attribute values to the element.
+ $cell.attr('style', newProps.join(';'));
+ });
+ this.$link.text(this.showText).data('pegged', 0);
+ // Refresh the toggle link.
+ $(window).trigger('resize.tableresponsive');
+ }
+ },
},
- });
+ );
// Make the TableResponsive object available in the Drupal namespace.
Drupal.TableResponsive = TableResponsive;
-}(jQuery, Drupal, window));
+})(jQuery, Drupal, window);
diff --git a/core/misc/tableselect.es6.js b/core/misc/tableselect.es6.js
index d3f852d..475efa6 100644
--- a/core/misc/tableselect.es6.js
+++ b/core/misc/tableselect.es6.js
@@ -3,7 +3,7 @@
* Table select functionality.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Initialize tableSelects.
*
@@ -26,7 +26,7 @@
/**
* Callback used in {@link Drupal.behaviors.tableSelect}.
*/
- Drupal.tableSelect = function () {
+ Drupal.tableSelect = function() {
// Do not add a "Select all" checkbox if there are no rows with checkboxes
// in the table.
if ($(this).find('td input[type="checkbox"]').length === 0) {
@@ -43,80 +43,106 @@
selectAll: Drupal.t('Select all rows in this table'),
selectNone: Drupal.t('Deselect all rows in this table'),
};
- const updateSelectAll = function (state) {
+ const updateSelectAll = function(state) {
// Update table's select-all checkbox (and sticky header's if available).
- $table.prev('table.sticky-header').addBack().find('th.select-all input[type="checkbox"]').each(function () {
- const $checkbox = $(this);
- const stateChanged = $checkbox.prop('checked') !== state;
-
- $checkbox.attr('title', state ? strings.selectNone : strings.selectAll);
-
- /**
- * @checkbox {HTMLElement}
- */
- if (stateChanged) {
- $checkbox.prop('checked', state).trigger('change');
- }
- });
- };
-
- // Find all <th> with class select-all, and insert the check all checkbox.
- $table.find('th.select-all').prepend($('<input type="checkbox" class="form-checkbox" />').attr('title', strings.selectAll)).on('click', (event) => {
- if ($(event.target).is('input[type="checkbox"]')) {
- // Loop through all checkboxes and set their state to the select all
- // checkbox' state.
- checkboxes.each(function () {
+ $table
+ .prev('table.sticky-header')
+ .addBack()
+ .find('th.select-all input[type="checkbox"]')
+ .each(function() {
const $checkbox = $(this);
- const stateChanged = $checkbox.prop('checked') !== event.target.checked;
+ const stateChanged = $checkbox.prop('checked') !== state;
+
+ $checkbox.attr(
+ 'title',
+ state ? strings.selectNone : strings.selectAll,
+ );
/**
* @checkbox {HTMLElement}
*/
if (stateChanged) {
- $checkbox.prop('checked', event.target.checked).trigger('change');
+ $checkbox.prop('checked', state).trigger('change');
}
- // Either add or remove the selected class based on the state of the
- // check all checkbox.
-
- /**
- * @checkbox {HTMLElement}
- */
- $checkbox.closest('tr').toggleClass('selected', this.checked);
});
- // Update the title and the state of the check all box.
- updateSelectAll(event.target.checked);
- }
- });
+ };
+
+ // Find all <th> with class select-all, and insert the check all checkbox.
+ $table
+ .find('th.select-all')
+ .prepend(
+ $('<input type="checkbox" class="form-checkbox" />').attr(
+ 'title',
+ strings.selectAll,
+ ),
+ )
+ .on('click', event => {
+ if ($(event.target).is('input[type="checkbox"]')) {
+ // Loop through all checkboxes and set their state to the select all
+ // checkbox' state.
+ checkboxes.each(function() {
+ const $checkbox = $(this);
+ const stateChanged =
+ $checkbox.prop('checked') !== event.target.checked;
+
+ /**
+ * @checkbox {HTMLElement}
+ */
+ if (stateChanged) {
+ $checkbox.prop('checked', event.target.checked).trigger('change');
+ }
+ // Either add or remove the selected class based on the state of the
+ // check all checkbox.
+
+ /**
+ * @checkbox {HTMLElement}
+ */
+ $checkbox.closest('tr').toggleClass('selected', this.checked);
+ });
+ // Update the title and the state of the check all box.
+ updateSelectAll(event.target.checked);
+ }
+ });
// For each of the checkboxes within the table that are not disabled.
- checkboxes = $table.find('td input[type="checkbox"]:enabled').on('click', function (e) {
- // Either add or remove the selected class based on the state of the
- // check all checkbox.
-
- /**
- * @this {HTMLElement}
- */
- $(this).closest('tr').toggleClass('selected', this.checked);
-
- // If this is a shift click, we need to highlight everything in the
- // range. Also make sure that we are actually checking checkboxes
- // over a range and that a checkbox has been checked or unchecked before.
- if (e.shiftKey && lastChecked && lastChecked !== e.target) {
- // We use the checkbox's parent <tr> to do our range searching.
- Drupal.tableSelectRange($(e.target).closest('tr')[0], $(lastChecked).closest('tr')[0], e.target.checked);
- }
+ checkboxes = $table
+ .find('td input[type="checkbox"]:enabled')
+ .on('click', function(e) {
+ // Either add or remove the selected class based on the state of the
+ // check all checkbox.
+
+ /**
+ * @this {HTMLElement}
+ */
+ $(this)
+ .closest('tr')
+ .toggleClass('selected', this.checked);
+
+ // If this is a shift click, we need to highlight everything in the
+ // range. Also make sure that we are actually checking checkboxes
+ // over a range and that a checkbox has been checked or unchecked before.
+ if (e.shiftKey && lastChecked && lastChecked !== e.target) {
+ // We use the checkbox's parent <tr> to do our range searching.
+ Drupal.tableSelectRange(
+ $(e.target).closest('tr')[0],
+ $(lastChecked).closest('tr')[0],
+ e.target.checked,
+ );
+ }
- // If all checkboxes are checked, make sure the select-all one is checked
- // too, otherwise keep unchecked.
- updateSelectAll((checkboxes.length === checkboxes.filter(':checked').length));
+ // If all checkboxes are checked, make sure the select-all one is checked
+ // too, otherwise keep unchecked.
+ updateSelectAll(
+ checkboxes.length === checkboxes.filter(':checked').length,
+ );
- // Keep track of the last checked checkbox.
- lastChecked = e.target;
- });
+ // Keep track of the last checked checkbox.
+ lastChecked = e.target;
+ });
// If all checkboxes are checked on page load, make sure the select-all one
// is checked too, otherwise keep unchecked.
- updateSelectAll((checkboxes.length === checkboxes.filter(':checked').length));
+ updateSelectAll(checkboxes.length === checkboxes.filter(':checked').length);
};
/**
@@ -127,9 +153,10 @@
* @param {bool} state
* The state to set on the range.
*/
- Drupal.tableSelectRange = function (from, to, state) {
+ Drupal.tableSelectRange = function(from, to, state) {
// We determine the looping mode based on the order of from and to.
- const mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling';
+ const mode =
+ from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling';
// Traverse through the sibling nodes.
for (let i = from[mode]; i; i = i[mode]) {
@@ -155,4 +182,4 @@
}
}
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/timezone.es6.js b/core/misc/timezone.es6.js
index 0df3f9f..64c88c7 100644
--- a/core/misc/timezone.es6.js
+++ b/core/misc/timezone.es6.js
@@ -3,7 +3,7 @@
* Timezone detection.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Set the client's system time zone as default values of form fields.
*
@@ -11,7 +11,9 @@
*/
Drupal.behaviors.setTimezone = {
attach(context, settings) {
- const $timezone = $(context).find('.timezone-detect').once('timezone');
+ const $timezone = $(context)
+ .find('.timezone-detect')
+ .once('timezone');
if ($timezone.length) {
const dateString = Date();
// In some client environments, date strings include a time zone
@@ -69,4 +71,4 @@
}
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/misc/vertical-tabs.es6.js b/core/misc/vertical-tabs.es6.js
index c0427bb..7a0fd0e 100644
--- a/core/misc/vertical-tabs.es6.js
+++ b/core/misc/vertical-tabs.es6.js
@@ -12,7 +12,7 @@
* @event summaryUpdated
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Show the parent vertical tab pane of a targeted page fragment.
*
@@ -26,7 +26,9 @@
*/
const handleFragmentLinkClickOrHashChange = (e, $target) => {
$target.parents('.vertical-tabs__pane').each((index, pane) => {
- $(pane).data('verticalTab').focus();
+ $(pane)
+ .data('verticalTab')
+ .focus();
});
};
@@ -56,62 +58,77 @@
/**
* Binds a listener to handle fragment link clicks and URL hash changes.
*/
- $('body').once('vertical-tabs-fragments').on('formFragmentLinkClickOrHashChange.verticalTabs', handleFragmentLinkClickOrHashChange);
+ $('body')
+ .once('vertical-tabs-fragments')
+ .on(
+ 'formFragmentLinkClickOrHashChange.verticalTabs',
+ handleFragmentLinkClickOrHashChange,
+ );
- $(context).find('[data-vertical-tabs-panes]').once('vertical-tabs').each(function () {
- const $this = $(this).addClass('vertical-tabs__panes');
- const focusID = $this.find(':hidden.vertical-tabs__active-tab').val();
- let tabFocus;
+ $(context)
+ .find('[data-vertical-tabs-panes]')
+ .once('vertical-tabs')
+ .each(function() {
+ const $this = $(this).addClass('vertical-tabs__panes');
+ const focusID = $this.find(':hidden.vertical-tabs__active-tab').val();
+ let tabFocus;
- // Check if there are some details that can be converted to
- // vertical-tabs.
- const $details = $this.find('> details');
- if ($details.length === 0) {
- return;
- }
+ // Check if there are some details that can be converted to
+ // vertical-tabs.
+ const $details = $this.find('> details');
+ if ($details.length === 0) {
+ return;
+ }
- // Create the tab column.
- const tabList = $('<ul class="vertical-tabs__menu"></ul>');
- $this.wrap('<div class="vertical-tabs clearfix"></div>').before(tabList);
+ // Create the tab column.
+ const tabList = $('<ul class="vertical-tabs__menu"></ul>');
+ $this
+ .wrap('<div class="vertical-tabs clearfix"></div>')
+ .before(tabList);
- // Transform each details into a tab.
- $details.each(function () {
- const $that = $(this);
- const verticalTab = new Drupal.verticalTab({
- title: $that.find('> summary').text(),
- details: $that,
+ // Transform each details into a tab.
+ $details.each(function() {
+ const $that = $(this);
+ const verticalTab = new Drupal.verticalTab({
+ title: $that.find('> summary').text(),
+ details: $that,
+ });
+ tabList.append(verticalTab.item);
+ $that
+ .removeClass('collapsed')
+ // prop() can't be used on browsers not supporting details element,
+ // the style won't apply to them if prop() is used.
+ .attr('open', true)
+ .addClass('vertical-tabs__pane')
+ .data('verticalTab', verticalTab);
+ if (this.id === focusID) {
+ tabFocus = $that;
+ }
});
- tabList.append(verticalTab.item);
- $that
- .removeClass('collapsed')
- // prop() can't be used on browsers not supporting details element,
- // the style won't apply to them if prop() is used.
- .attr('open', true)
- .addClass('vertical-tabs__pane')
- .data('verticalTab', verticalTab);
- if (this.id === focusID) {
- tabFocus = $that;
- }
- });
- $(tabList).find('> li').eq(0).addClass('first');
- $(tabList).find('> li').eq(-1).addClass('last');
+ $(tabList)
+ .find('> li')
+ .eq(0)
+ .addClass('first');
+ $(tabList)
+ .find('> li')
+ .eq(-1)
+ .addClass('last');
- if (!tabFocus) {
- // If the current URL has a fragment and one of the tabs contains an
- // element that matches the URL fragment, activate that tab.
- const $locationHash = $this.find(window.location.hash);
- if (window.location.hash && $locationHash.length) {
- tabFocus = $locationHash.closest('.vertical-tabs__pane');
+ if (!tabFocus) {
+ // If the current URL has a fragment and one of the tabs contains an
+ // element that matches the URL fragment, activate that tab.
+ const $locationHash = $this.find(window.location.hash);
+ if (window.location.hash && $locationHash.length) {
+ tabFocus = $locationHash.closest('.vertical-tabs__pane');
+ } else {
+ tabFocus = $this.find('> .vertical-tabs__pane').eq(0);
+ }
}
- else {
- tabFocus = $this.find('> .vertical-tabs__pane').eq(0);
+ if (tabFocus.length) {
+ tabFocus.data('verticalTab').focus();
}
- }
- if (tabFocus.length) {
- tabFocus.data('verticalTab').focus();
- }
- });
+ });
},
};
@@ -131,25 +148,27 @@
*
* @listens event:summaryUpdated
*/
- Drupal.verticalTab = function (settings) {
+ Drupal.verticalTab = function(settings) {
const self = this;
$.extend(this, settings, Drupal.theme('verticalTab', settings));
this.link.attr('href', `#${settings.details.attr('id')}`);
- this.link.on('click', (e) => {
+ this.link.on('click', e => {
e.preventDefault();
self.focus();
});
// Keyboard events added:
// Pressing the Enter key will open the tab pane.
- this.link.on('keydown', (event) => {
+ this.link.on('keydown', event => {
if (event.keyCode === 13) {
event.preventDefault();
self.focus();
// Set focus on the first input field of the visible details/tab pane.
- $('.vertical-tabs__pane :input:visible:enabled').eq(0).trigger('focus');
+ $('.vertical-tabs__pane :input:visible:enabled')
+ .eq(0)
+ .trigger('focus');
}
});
@@ -161,14 +180,13 @@
};
Drupal.verticalTab.prototype = {
-
/**
* Displays the tab's content pane.
*/
focus() {
this.details
.siblings('.vertical-tabs__pane')
- .each(function () {
+ .each(function() {
const tab = $(this).data('verticalTab');
tab.details.hide();
tab.item.removeClass('is-selected');
@@ -180,7 +198,11 @@
this.item.addClass('is-selected');
// Mark the active tab for screen readers.
$('#active-vertical-tab').remove();
- this.link.append(`<span id="active-vertical-tab" class="visually-hidden">${Drupal.t('(active tab)')}</span>`);
+ this.link.append(
+ `<span id="active-vertical-tab" class="visually-hidden">${Drupal.t(
+ '(active tab)',
+ )}</span>`,
+ );
},
/**
@@ -240,7 +262,9 @@
// Hide the details element.
this.details.addClass('vertical-tab--hidden').hide();
// Focus the first visible tab (if there is one).
- const $firstTab = this.details.siblings('.vertical-tabs__pane:not(.vertical-tab--hidden)').eq(0);
+ const $firstTab = this.details
+ .siblings('.vertical-tabs__pane:not(.vertical-tab--hidden)')
+ .eq(0);
if ($firstTab.length) {
$firstTab.data('verticalTab').focus();
}
@@ -267,14 +291,23 @@
* (jQuery version)
* - summary: The jQuery element that contains the tab summary
*/
- Drupal.theme.verticalTab = function (settings) {
+ Drupal.theme.verticalTab = function(settings) {
const tab = {};
- tab.item = $('<li class="vertical-tabs__menu-item" tabindex="-1"></li>')
- .append(
- tab.link = $('<a href="#"></a>')
- .append(tab.title = $('<strong class="vertical-tabs__menu-item-title"></strong>').text(settings.title))
- .append(tab.summary = $('<span class="vertical-tabs__menu-item-summary"></span>')),
- );
+ tab.item = $(
+ '<li class="vertical-tabs__menu-item" tabindex="-1"></li>',
+ ).append(
+ (tab.link = $('<a href="#"></a>')
+ .append(
+ (tab.title = $(
+ '<strong class="vertical-tabs__menu-item-title"></strong>',
+ ).text(settings.title)),
+ )
+ .append(
+ (tab.summary = $(
+ '<span class="vertical-tabs__menu-item-summary"></span>',
+ )),
+ )),
+ );
return tab;
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/big_pipe/js/big_pipe.es6.js b/core/modules/big_pipe/js/big_pipe.es6.js
index afaa6aa..3659b99 100644
--- a/core/modules/big_pipe/js/big_pipe.es6.js
+++ b/core/modules/big_pipe/js/big_pipe.es6.js
@@ -3,7 +3,7 @@
* Renders BigPipe placeholders using Drupal's Ajax system.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Maps textContent of <script type="application/vnd.drupal-ajax"> to an AJAX response.
*
@@ -20,8 +20,7 @@
try {
return JSON.parse(content);
- }
- catch (e) {
+ } catch (e) {
return false;
}
}
@@ -37,11 +36,15 @@
* Script tag created by BigPipe.
*/
function bigPipeProcessPlaceholderReplacement(index, placeholderReplacement) {
- const placeholderId = placeholderReplacement.getAttribute('data-big-pipe-replacement-for-placeholder-with-id');
+ const placeholderId = placeholderReplacement.getAttribute(
+ 'data-big-pipe-replacement-for-placeholder-with-id',
+ );
const content = this.textContent.trim();
// Ignore any placeholders that are not in the known placeholder list. Used
// to avoid someone trying to XSS the site via the placeholdering mechanism.
- if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') {
+ if (
+ typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined'
+ ) {
const response = mapTextContentToAjaxResponse(content);
// If we try to parse the content too early (when the JSON containing Ajax
// commands is still arriving), textContent will be empty or incomplete.
@@ -51,8 +54,7 @@
* @see bigPipeProcessDocument()
*/
$(this).removeOnce('big-pipe');
- }
- else {
+ } else {
// Create a Drupal.Ajax object without associating an element, a
// progress indicator or a URL.
const ajaxObject = Drupal.ajax({
@@ -93,7 +95,8 @@
return false;
}
- $(context).find('script[data-big-pipe-replacement-for-placeholder-with-id]')
+ $(context)
+ .find('script[data-big-pipe-replacement-for-placeholder-with-id]')
.once('big-pipe')
.each(bigPipeProcessPlaceholderReplacement);
@@ -127,4 +130,4 @@
}
bigPipeProcessDocument(document);
});
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/block/js/block.admin.es6.js b/core/modules/block/js/block.admin.es6.js
index 780ea12..197bc4b 100644
--- a/core/modules/block/js/block.admin.es6.js
+++ b/core/modules/block/js/block.admin.es6.js
@@ -3,7 +3,7 @@
* Block admin behaviors.
*/
-(function ($, Drupal, debounce) {
+(function($, Drupal, debounce) {
/**
* Filters the block list by a text input search string.
*
@@ -33,7 +33,9 @@
* The jQuery event for the keyup event that triggered the filter.
*/
function filterBlockList(e) {
- const query = $(e.target).val().toLowerCase();
+ const query = $(e.target)
+ .val()
+ .toLowerCase();
/**
* Shows or hides the block entry based on the query.
@@ -46,7 +48,11 @@
function toggleBlockEntry(index, label) {
const $label = $(label);
const $row = $label.parent().parent();
- const textMatch = $label.text().toLowerCase().indexOf(query) !== -1;
+ const textMatch =
+ $label
+ .text()
+ .toLowerCase()
+ .indexOf(query) !== -1;
$row.toggle(textMatch);
}
@@ -60,10 +66,12 @@
'@count blocks are available in the modified list.',
),
);
- }
- else {
- $filterRows.each(function (index) {
- $(this).parent().parent().show();
+ } else {
+ $filterRows.each(function(index) {
+ $(this)
+ .parent()
+ .parent()
+ .show();
});
}
}
@@ -86,15 +94,24 @@
Drupal.behaviors.blockHighlightPlacement = {
attach(context, settings) {
if (settings.blockPlacement) {
- $(context).find('[data-drupal-selector="edit-blocks"]').once('block-highlight').each(function () {
- const $container = $(this);
- // Just scrolling the document.body will not work in Firefox. The html
- // element is needed as well.
- $('html, body').animate({
- scrollTop: ($('.js-block-placed').offset().top - $container.offset().top) + $container.scrollTop(),
- }, 500);
- });
+ $(context)
+ .find('[data-drupal-selector="edit-blocks"]')
+ .once('block-highlight')
+ .each(function() {
+ const $container = $(this);
+ // Just scrolling the document.body will not work in Firefox. The html
+ // element is needed as well.
+ $('html, body').animate(
+ {
+ scrollTop:
+ $('.js-block-placed').offset().top -
+ $container.offset().top +
+ $container.scrollTop(),
+ },
+ 500,
+ );
+ });
}
},
};
-}(jQuery, Drupal, Drupal.debounce));
+})(jQuery, Drupal, Drupal.debounce);
diff --git a/core/modules/block/js/block.es6.js b/core/modules/block/js/block.es6.js
index 7bdbab0..68af995 100644
--- a/core/modules/block/js/block.es6.js
+++ b/core/modules/block/js/block.es6.js
@@ -3,7 +3,7 @@
* Block behaviors.
*/
-(function ($, window, Drupal) {
+(function($, window, Drupal) {
/**
* Provide the summary information for the block settings vertical tabs.
*
@@ -32,7 +32,9 @@
*/
function checkboxesSummary(context) {
const vals = [];
- const $checkboxes = $(context).find('input[type="checkbox"]:checked + label');
+ const $checkboxes = $(context).find(
+ 'input[type="checkbox"]:checked + label',
+ );
const il = $checkboxes.length;
for (let i = 0; i < il; i++) {
vals.push($($checkboxes[i]).html());
@@ -43,10 +45,16 @@
return vals.join(', ');
}
- $('[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]').drupalSetSummary(checkboxesSummary);
+ $(
+ '[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]',
+ ).drupalSetSummary(checkboxesSummary);
- $('[data-drupal-selector="edit-visibility-request-path"]').drupalSetSummary((context) => {
- const $pages = $(context).find('textarea[name="visibility[request_path][pages]"]');
+ $(
+ '[data-drupal-selector="edit-visibility-request-path"]',
+ ).drupalSetSummary(context => {
+ const $pages = $(context).find(
+ 'textarea[name="visibility[request_path][pages]"]',
+ );
if (!$pages.val()) {
return Drupal.t('Not restricted');
}
@@ -70,7 +78,10 @@
Drupal.behaviors.blockDrag = {
attach(context, settings) {
// tableDrag is required and we should be on the blocks admin page.
- if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag.blocks === 'undefined') {
+ if (
+ typeof Drupal.tableDrag === 'undefined' ||
+ typeof Drupal.tableDrag.blocks === 'undefined'
+ ) {
return;
}
@@ -83,19 +94,25 @@
* The jQuery object representing the table row.
*/
function checkEmptyRegions(table, rowObject) {
- table.find('tr.region-message').each(function () {
+ table.find('tr.region-message').each(function() {
const $this = $(this);
// If the dragged row is in this region, but above the message row,
// swap it down one space.
if ($this.prev('tr').get(0) === rowObject.element) {
// Prevent a recursion problem when using the keyboard to move rows
// up.
- if ((rowObject.method !== 'keyboard' || rowObject.direction === 'down')) {
+ if (
+ rowObject.method !== 'keyboard' ||
+ rowObject.direction === 'down'
+ ) {
rowObject.swap('after', this);
}
}
// This region has become empty.
- if ($this.next('tr').is(':not(.draggable)') || $this.next('tr').length === 0) {
+ if (
+ $this.next('tr').is(':not(.draggable)') ||
+ $this.next('tr').length === 0
+ ) {
$this.removeClass('region-populated').addClass('region-empty');
}
// This region has become populated.
@@ -153,20 +170,23 @@
// Get the blocks tableDrag object.
const tableDrag = Drupal.tableDrag.blocks;
// Add a handler for when a row is swapped, update empty regions.
- tableDrag.row.prototype.onSwap = function (swappedRow) {
+ tableDrag.row.prototype.onSwap = function(swappedRow) {
checkEmptyRegions(table, this);
updateLastPlaced(table, this);
};
// Add a handler so when a row is dropped, update fields dropped into
// new regions.
- tableDrag.onDrop = function () {
+ tableDrag.onDrop = function() {
const dragObject = this;
const $rowElement = $(dragObject.rowObject.element);
// Use "region-message" row instead of "region" row because
// "region-{region_name}-message" is less prone to regexp match errors.
const regionRow = $rowElement.prevAll('tr.region-message').get(0);
- const regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
+ const regionName = regionRow.className.replace(
+ /([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/,
+ '$2',
+ );
const regionField = $rowElement.find('select.block-region-select');
// Check whether the newly picked region is available for this block.
if (regionField.find(`option[value=${regionName}]`).length === 0) {
@@ -181,9 +201,16 @@
// Update region and weight fields if the region has been changed.
if (!regionField.is(`.block-region-${regionName}`)) {
const weightField = $rowElement.find('select.block-weight');
- const oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
- regionField.removeClass(`block-region-${oldRegionName}`).addClass(`block-region-${regionName}`);
- weightField.removeClass(`block-weight-${oldRegionName}`).addClass(`block-weight-${regionName}`);
+ const oldRegionName = weightField[0].className.replace(
+ /([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/,
+ '$2',
+ );
+ regionField
+ .removeClass(`block-region-${oldRegionName}`)
+ .addClass(`block-region-${regionName}`);
+ weightField
+ .removeClass(`block-weight-${oldRegionName}`)
+ .addClass(`block-weight-${regionName}`);
regionField.val(regionName);
}
@@ -191,16 +218,22 @@
};
// Add the behavior to each region select list.
- $(context).find('select.block-region-select').once('block-region-select')
- .on('change', function (event) {
+ $(context)
+ .find('select.block-region-select')
+ .once('block-region-select')
+ .on('change', function(event) {
// Make our new row and select field.
const row = $(this).closest('tr');
const select = $(this);
// Find the correct region and insert the row as the last in the
// region.
tableDrag.rowObject = new tableDrag.row(row[0]);
- const regionMessage = table.find(`.region-${select[0].value}-message`);
- const regionItems = regionMessage.nextUntil('.region-message, .region-title');
+ const regionMessage = table.find(
+ `.region-${select[0].value}-message`,
+ );
+ const regionItems = regionMessage.nextUntil(
+ '.region-message, .region-title',
+ );
if (regionItems.length) {
regionItems.last().after(row);
}
@@ -215,7 +248,10 @@
updateLastPlaced(table, row);
// Show unsaved changes warning.
if (!tableDrag.changed) {
- $(Drupal.theme('tableDragChangedWarning')).insertBefore(tableDrag.table).hide().fadeIn('slow');
+ $(Drupal.theme('tableDragChangedWarning'))
+ .insertBefore(tableDrag.table)
+ .hide()
+ .fadeIn('slow');
tableDrag.changed = true;
}
// Remove focus from selectbox.
@@ -223,4 +259,4 @@
});
},
};
-}(jQuery, window, Drupal));
+})(jQuery, window, Drupal);
diff --git a/core/modules/book/book.es6.js b/core/modules/book/book.es6.js
index 5458e61..deb518b 100644
--- a/core/modules/book/book.es6.js
+++ b/core/modules/book/book.es6.js
@@ -3,7 +3,7 @@
* Javascript behaviors for the Book module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Adds summaries to the book outline form.
*
@@ -14,19 +14,21 @@
*/
Drupal.behaviors.bookDetailsSummaries = {
attach(context) {
- $(context).find('.book-outline-form').drupalSetSummary((context) => {
- const $select = $(context).find('.book-title-select');
- const val = $select.val();
+ $(context)
+ .find('.book-outline-form')
+ .drupalSetSummary(context => {
+ const $select = $(context).find('.book-title-select');
+ const val = $select.val();
- if (val === '0') {
- return Drupal.t('Not in book');
- }
- if (val === 'new') {
- return Drupal.t('New book');
- }
+ if (val === '0') {
+ return Drupal.t('Not in book');
+ }
+ if (val === 'new') {
+ return Drupal.t('New book');
+ }
- return Drupal.checkPlain($select.find(':selected').text());
- });
+ return Drupal.checkPlain($select.find(':selected').text());
+ });
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/ckeditor/js/ckeditor.admin.es6.js b/core/modules/ckeditor/js/ckeditor.admin.es6.js
index 687169f..b4c2d21 100644
--- a/core/modules/ckeditor/js/ckeditor.admin.es6.js
+++ b/core/modules/ckeditor/js/ckeditor.admin.es6.js
@@ -3,7 +3,7 @@
* CKEditor button and group configuration user interface.
*/
-(function ($, Drupal, drupalSettings, _) {
+(function($, Drupal, drupalSettings, _) {
Drupal.ckeditor = Drupal.ckeditor || {};
/**
@@ -19,7 +19,9 @@
Drupal.behaviors.ckeditorAdmin = {
attach(context) {
// Process the CKEditor configuration fragment once.
- const $configurationForm = $(context).find('.ckeditor-toolbar-configuration').once('ckeditor-configuration');
+ const $configurationForm = $(context)
+ .find('.ckeditor-toolbar-configuration')
+ .once('ckeditor-configuration');
if ($configurationForm.length) {
const $textarea = $configurationForm
// Hide the textarea that contains the serialized representation of the
@@ -64,13 +66,24 @@
// really means that all CKEditor toolbar buttons have been removed.
// Hence,all editor features will be removed, so any reactions from
// filters will be undone.
- const $configurationForm = $(context).find('.ckeditor-toolbar-configuration').findOnce('ckeditor-configuration');
- if ($configurationForm.length && Drupal.ckeditor.models && Drupal.ckeditor.models.Model) {
+ const $configurationForm = $(context)
+ .find('.ckeditor-toolbar-configuration')
+ .findOnce('ckeditor-configuration');
+ if (
+ $configurationForm.length &&
+ Drupal.ckeditor.models &&
+ Drupal.ckeditor.models.Model
+ ) {
const config = Drupal.ckeditor.models.Model.toJSON().activeEditorConfig;
const buttons = Drupal.ckeditor.views.controller.getButtonList(config);
- const $activeToolbar = $('.ckeditor-toolbar-configuration').find('.ckeditor-toolbar-active');
+ const $activeToolbar = $('.ckeditor-toolbar-configuration').find(
+ '.ckeditor-toolbar-active',
+ );
for (let i = 0; i < buttons.length; i++) {
- $activeToolbar.trigger('CKEditorToolbarChanged', ['removed', buttons[i]]);
+ $activeToolbar.trigger('CKEditorToolbarChanged', [
+ 'removed',
+ buttons[i],
+ ]);
}
}
},
@@ -82,7 +95,6 @@
* @namespace
*/
Drupal.ckeditor = {
-
/**
* A hash of View instances.
*
@@ -125,8 +137,7 @@
view.isProcessing = true;
Drupal.ckeditor.openGroupNameDialog(view, $group, callback);
- }
- else {
+ } else {
view.model.set('isDirty', true);
callback(true);
}
@@ -152,12 +163,18 @@
}
// If there are any rows with just a placeholder group, mark the row as a
// placeholder.
- $row.parent().children().each(function () {
- $row = $(this);
- if ($row.find('.ckeditor-toolbar-group').not('.placeholder').length === 0) {
- $row.addClass('placeholder');
- }
- });
+ $row
+ .parent()
+ .children()
+ .each(function() {
+ $row = $(this);
+ if (
+ $row.find('.ckeditor-toolbar-group').not('.placeholder').length ===
+ 0
+ ) {
+ $row.addClass('placeholder');
+ }
+ });
view.model.set('isDirty', true);
},
@@ -173,7 +190,7 @@
* been closed.
*/
openGroupNameDialog(view, $group, callback) {
- callback = callback || function () {};
+ callback = callback || function() {};
/**
* Validates the string provided as a button group title.
@@ -194,7 +211,11 @@
.find('input')
.addClass('error')
.attr('aria-invalid', 'true');
- $(`<div class="description" >${Drupal.t('Please provide a name for the button group.')}</div>`).insertAfter(form.elements[0]);
+ $(
+ `<div class="description" >${Drupal.t(
+ 'Please provide a name for the button group.',
+ )}</div>`,
+ ).insertAfter(form.elements[0]);
}
return true;
}
@@ -239,7 +260,9 @@
// Remove all whitespace from the name, lowercase it and ensure
// HTML-safe encoding, then use this as the group ID for CKEditor
// configuration UI accessibility purposes only.
- const groupID = `ckeditor-toolbar-group-aria-label-for-${Drupal.checkPlain(name.toLowerCase().replace(/\s/g, '-'))}`;
+ const groupID = `ckeditor-toolbar-group-aria-label-for-${Drupal.checkPlain(
+ name.toLowerCase().replace(/\s/g, '-'),
+ )}`;
$group
// Update the group container.
.removeAttr('aria-label')
@@ -276,10 +299,16 @@
if (action === 'apply') {
shutdown();
// Apply the provided name to the button group label.
- namePlaceholderGroup($group, Drupal.checkPlain(form.elements[0].value));
+ namePlaceholderGroup(
+ $group,
+ Drupal.checkPlain(form.elements[0].value),
+ );
// Remove placeholder classes so that new placeholders will be
// inserted.
- $group.closest('.ckeditor-row.placeholder').addBack().removeClass('placeholder');
+ $group
+ .closest('.ckeditor-row.placeholder')
+ .addBack()
+ .removeClass('placeholder');
// Invoke a user-provided callback and indicate success.
callback(true, $group);
@@ -290,7 +319,9 @@
}
// Create a Drupal dialog that will get a button group name from the user.
- const $ckeditorButtonGroupNameForm = $(Drupal.theme('ckeditorButtonGroupNameForm'));
+ const $ckeditorButtonGroupNameForm = $(
+ Drupal.theme('ckeditorButtonGroupNameForm'),
+ );
const dialog = Drupal.dialog($ckeditorButtonGroupNameForm.get(0), {
title: Drupal.t('Button group name'),
dialogClass: 'ckeditor-name-toolbar-group',
@@ -316,7 +347,7 @@
const $widget = $form.parent();
$widget.find('.ui-dialog-titlebar-close').remove();
// Set a click handler on the input and button in the form.
- $widget.on('keypress.ckeditor', 'input, button', (event) => {
+ $widget.on('keypress.ckeditor', 'input, button', event => {
// React to enter key press.
if (event.keyCode === 13) {
const $target = $(event.currentTarget);
@@ -334,11 +365,21 @@
}
});
// Announce to the user that a modal dialog is open.
- let text = Drupal.t('Editing the name of the new button group in a dialog.');
- if (typeof $group.attr('data-drupal-ckeditor-toolbar-group-name') !== 'undefined') {
- text = Drupal.t('Editing the name of the "@groupName" button group in a dialog.', {
- '@groupName': $group.attr('data-drupal-ckeditor-toolbar-group-name'),
- });
+ let text = Drupal.t(
+ 'Editing the name of the new button group in a dialog.',
+ );
+ if (
+ typeof $group.attr('data-drupal-ckeditor-toolbar-group-name') !==
+ 'undefined'
+ ) {
+ text = Drupal.t(
+ 'Editing the name of the "@groupName" button group in a dialog.',
+ {
+ '@groupName': $group.attr(
+ 'data-drupal-ckeditor-toolbar-group-name',
+ ),
+ },
+ );
}
Drupal.announce(text);
},
@@ -352,14 +393,17 @@
// name or cancel the button placement before taking any other action.
dialog.showModal();
- $(document.querySelector('.ckeditor-name-toolbar-group').querySelector('input'))
+ $(
+ document
+ .querySelector('.ckeditor-name-toolbar-group')
+ .querySelector('input'),
+ )
// When editing, set the "group name" input in the form to the current
// value.
.attr('value', $group.attr('data-drupal-ckeditor-toolbar-group-name'))
// Focus on the "group name" input in the form.
.trigger('focus');
},
-
};
/**
@@ -373,20 +417,23 @@
Drupal.behaviors.ckeditorAdminButtonPluginSettings = {
attach(context) {
const $context = $(context);
- const $ckeditorPluginSettings = $context.find('#ckeditor-plugin-settings').once('ckeditor-plugin-settings');
+ const $ckeditorPluginSettings = $context
+ .find('#ckeditor-plugin-settings')
+ .once('ckeditor-plugin-settings');
if ($ckeditorPluginSettings.length) {
// Hide all button-dependent plugin settings initially.
- $ckeditorPluginSettings.find('[data-ckeditor-buttons]').each(function () {
- const $this = $(this);
- if ($this.data('verticalTab')) {
- $this.data('verticalTab').tabHide();
- }
- else {
- // On very narrow viewports, Vertical Tabs are disabled.
- $this.hide();
- }
- $this.data('ckeditorButtonPluginSettingsActiveButtons', []);
- });
+ $ckeditorPluginSettings
+ .find('[data-ckeditor-buttons]')
+ .each(function() {
+ const $this = $(this);
+ if ($this.data('verticalTab')) {
+ $this.data('verticalTab').tabHide();
+ } else {
+ // On very narrow viewports, Vertical Tabs are disabled.
+ $this.hide();
+ }
+ $this.data('ckeditorButtonPluginSettingsActiveButtons', []);
+ });
// Whenever a button is added or removed, check if we should show or
// hide the corresponding plugin settings. (Note that upon
@@ -396,44 +443,50 @@
$context
.find('.ckeditor-toolbar-active')
.off('CKEditorToolbarChanged.ckeditorAdminPluginSettings')
- .on('CKEditorToolbarChanged.ckeditorAdminPluginSettings', (event, action, button) => {
- const $pluginSettings = $ckeditorPluginSettings
- .find(`[data-ckeditor-buttons~=${button}]`);
-
- // No settings for this button.
- if ($pluginSettings.length === 0) {
- return;
- }
-
- const verticalTab = $pluginSettings.data('verticalTab');
- const activeButtons = $pluginSettings.data('ckeditorButtonPluginSettingsActiveButtons');
- if (action === 'added') {
- activeButtons.push(button);
- // Show this plugin's settings if >=1 of its buttons are active.
- if (verticalTab) {
- verticalTab.tabShow();
- }
- else {
- // On very narrow viewports, Vertical Tabs remain fieldsets.
- $pluginSettings.show();
+ .on(
+ 'CKEditorToolbarChanged.ckeditorAdminPluginSettings',
+ (event, action, button) => {
+ const $pluginSettings = $ckeditorPluginSettings.find(
+ `[data-ckeditor-buttons~=${button}]`,
+ );
+
+ // No settings for this button.
+ if ($pluginSettings.length === 0) {
+ return;
}
- }
- else {
- // Remove this button from the list of active buttons.
- activeButtons.splice(activeButtons.indexOf(button), 1);
- // Show this plugin's settings 0 of its buttons are active.
- if (activeButtons.length === 0) {
+
+ const verticalTab = $pluginSettings.data('verticalTab');
+ const activeButtons = $pluginSettings.data(
+ 'ckeditorButtonPluginSettingsActiveButtons',
+ );
+ if (action === 'added') {
+ activeButtons.push(button);
+ // Show this plugin's settings if >=1 of its buttons are active.
if (verticalTab) {
- verticalTab.tabHide();
+ verticalTab.tabShow();
+ } else {
+ // On very narrow viewports, Vertical Tabs remain fieldsets.
+ $pluginSettings.show();
}
- else {
- // On very narrow viewports, Vertical Tabs are disabled.
- $pluginSettings.hide();
+ } else {
+ // Remove this button from the list of active buttons.
+ activeButtons.splice(activeButtons.indexOf(button), 1);
+ // Show this plugin's settings 0 of its buttons are active.
+ if (activeButtons.length === 0) {
+ if (verticalTab) {
+ verticalTab.tabHide();
+ } else {
+ // On very narrow viewports, Vertical Tabs are disabled.
+ $pluginSettings.hide();
+ }
}
}
- }
- $pluginSettings.data('ckeditorButtonPluginSettingsActiveButtons', activeButtons);
- });
+ $pluginSettings.data(
+ 'ckeditorButtonPluginSettingsActiveButtons',
+ activeButtons,
+ );
+ },
+ );
}
},
};
@@ -444,7 +497,7 @@
* @return {string}
* A HTML string for a CKEditor row.
*/
- Drupal.theme.ckeditorRow = function () {
+ Drupal.theme.ckeditorRow = function() {
return '<li class="ckeditor-row placeholder" role="group"><ul class="ckeditor-toolbar-groups clearfix"></ul></li>';
};
@@ -454,11 +507,16 @@
* @return {string}
* A HTML string for a CKEditor button group.
*/
- Drupal.theme.ckeditorToolbarGroup = function () {
+ Drupal.theme.ckeditorToolbarGroup = function() {
let group = '';
- group += `<li class="ckeditor-toolbar-group placeholder" role="presentation" aria-label="${Drupal.t('Place a button to create a new button group.')}">`;
- group += `<h3 class="ckeditor-toolbar-group-name">${Drupal.t('New group')}</h3>`;
- group += '<ul class="ckeditor-buttons ckeditor-toolbar-group-buttons" role="toolbar" data-drupal-ckeditor-button-sorting="target"></ul>';
+ group += `<li class="ckeditor-toolbar-group placeholder" role="presentation" aria-label="${Drupal.t(
+ 'Place a button to create a new button group.',
+ )}">`;
+ group += `<h3 class="ckeditor-toolbar-group-name">${Drupal.t(
+ 'New group',
+ )}</h3>`;
+ group +=
+ '<ul class="ckeditor-buttons ckeditor-toolbar-group-buttons" role="toolbar" data-drupal-ckeditor-button-sorting="target"></ul>';
group += '</li>';
return group;
};
@@ -469,7 +527,7 @@
* @return {string}
* A HTML string for the form for the title of a CKEditor button group.
*/
- Drupal.theme.ckeditorButtonGroupNameForm = function () {
+ Drupal.theme.ckeditorButtonGroupNameForm = function() {
return '<form><input name="group-name" required="required"></form>';
};
@@ -479,7 +537,7 @@
* @return {string}
* A HTML string for the button to toggle group names.
*/
- Drupal.theme.ckeditorButtonGroupNamesToggle = function () {
+ Drupal.theme.ckeditorButtonGroupNamesToggle = function() {
return '<button class="link ckeditor-groupnames-toggle" aria-pressed="false"></button>';
};
@@ -489,7 +547,9 @@
* @return {string}
* A HTML string for the button to create a name for a new button group.
*/
- Drupal.theme.ckeditorNewButtonGroup = function () {
- return `<li class="ckeditor-add-new-group"><button aria-label="${Drupal.t('Add a CKEditor button group to the end of this row.')}">${Drupal.t('Add group')}</button></li>`;
+ Drupal.theme.ckeditorNewButtonGroup = function() {
+ return `<li class="ckeditor-add-new-group"><button aria-label="${Drupal.t(
+ 'Add a CKEditor button group to the end of this row.',
+ )}">${Drupal.t('Add group')}</button></li>`;
};
-}(jQuery, Drupal, drupalSettings, _));
+})(jQuery, Drupal, drupalSettings, _);
diff --git a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.es6.js b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.es6.js
index 89ab29f..5573794 100644
--- a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.es6.js
+++ b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.es6.js
@@ -3,7 +3,7 @@
* CKEditor 'drupalimage' plugin admin behavior.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Provides the summary for the "drupalimage" plugin settings vertical tab.
*
@@ -14,23 +14,32 @@
*/
Drupal.behaviors.ckeditorDrupalImageSettingsSummary = {
attach() {
- $('[data-ckeditor-plugin-id="drupalimage"]').drupalSetSummary((context) => {
- const root = 'input[name="editor[settings][plugins][drupalimage][image_upload]';
+ $('[data-ckeditor-plugin-id="drupalimage"]').drupalSetSummary(context => {
+ const root =
+ 'input[name="editor[settings][plugins][drupalimage][image_upload]';
const $status = $(`${root}[status]"]`);
const $maxFileSize = $(`${root}[max_size]"]`);
const $maxWidth = $(`${root}[max_dimensions][width]"]`);
const $maxHeight = $(`${root}[max_dimensions][height]"]`);
const $scheme = $(`${root}[scheme]"]:checked`);
- const maxFileSize = $maxFileSize.val() ? $maxFileSize.val() : $maxFileSize.attr('placeholder');
- const maxDimensions = ($maxWidth.val() && $maxHeight.val()) ? `(${$maxWidth.val()}x${$maxHeight.val()})` : '';
+ const maxFileSize = $maxFileSize.val()
+ ? $maxFileSize.val()
+ : $maxFileSize.attr('placeholder');
+ const maxDimensions =
+ $maxWidth.val() && $maxHeight.val()
+ ? `(${$maxWidth.val()}x${$maxHeight.val()})`
+ : '';
if (!$status.is(':checked')) {
return Drupal.t('Uploads disabled');
}
let output = '';
- output += Drupal.t('Uploads enabled, max size: @size @dimensions', { '@size': maxFileSize, '@dimensions': maxDimensions });
+ output += Drupal.t('Uploads enabled, max size: @size @dimensions', {
+ '@size': maxFileSize,
+ '@dimensions': maxDimensions,
+ });
if ($scheme.length) {
output += `<br />${$scheme.attr('data-label')}`;
}
@@ -38,4 +47,4 @@
});
},
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js
index 51b9509..2d4eb69 100644
--- a/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js
+++ b/core/modules/ckeditor/js/ckeditor.drupalimage.admin.js
@@ -24,7 +24,10 @@
}
var output = '';
- output += Drupal.t('Uploads enabled, max size: @size @dimensions', { '@size': maxFileSize, '@dimensions': maxDimensions });
+ output += Drupal.t('Uploads enabled, max size: @size @dimensions', {
+ '@size': maxFileSize,
+ '@dimensions': maxDimensions
+ });
if ($scheme.length) {
output += '<br />' + $scheme.attr('data-label');
}
diff --git a/core/modules/ckeditor/js/ckeditor.es6.js b/core/modules/ckeditor/js/ckeditor.es6.js
index c4ba156..2ce0949 100644
--- a/core/modules/ckeditor/js/ckeditor.es6.js
+++ b/core/modules/ckeditor/js/ckeditor.es6.js
@@ -3,12 +3,11 @@
* CKEditor implementation of {@link Drupal.editors} API.
*/
-(function (Drupal, debounce, CKEDITOR, $, displace, AjaxCommands) {
+(function(Drupal, debounce, CKEDITOR, $, displace, AjaxCommands) {
/**
* @namespace
*/
Drupal.editors.ckeditor = {
-
/**
* Editor attach callback.
*
@@ -31,7 +30,9 @@
// label so that screen readers say something that is understandable
// for end users.
const label = $(`label[for=${element.getAttribute('id')}]`).html();
- format.editorSettings.title = Drupal.t('Rich Text Editor, !label field', { '!label': label });
+ format.editorSettings.title = Drupal.t('Rich Text Editor, !label field', {
+ '!label': label,
+ });
return !!CKEDITOR.replace(element, format.editorSettings);
},
@@ -55,8 +56,7 @@
if (editor) {
if (trigger === 'serialize') {
editor.updateElement();
- }
- else {
+ } else {
editor.destroy();
element.removeAttribute('contentEditable');
}
@@ -79,9 +79,12 @@
onChange(element, callback) {
const editor = CKEDITOR.dom.element.get(element).getEditor();
if (editor) {
- editor.on('change', debounce(() => {
- callback(editor.getData());
- }, 400));
+ editor.on(
+ 'change',
+ debounce(() => {
+ callback(editor.getData());
+ }, 400),
+ );
// A temporary workaround to control scrollbar appearance when using
// autoGrow event to control editor's height.
@@ -89,17 +92,24 @@
editor.on('mode', () => {
const editable = editor.editable();
if (!editable.isInline()) {
- editor.on('autoGrow', (evt) => {
- const doc = evt.editor.document;
- const scrollable = CKEDITOR.env.quirks ? doc.getBody() : doc.getDocumentElement();
-
- if (scrollable.$.scrollHeight < scrollable.$.clientHeight) {
- scrollable.setStyle('overflow-y', 'hidden');
- }
- else {
- scrollable.removeStyle('overflow-y');
- }
- }, null, null, 10000);
+ editor.on(
+ 'autoGrow',
+ evt => {
+ const doc = evt.editor.document;
+ const scrollable = CKEDITOR.env.quirks
+ ? doc.getBody()
+ : doc.getDocumentElement();
+
+ if (scrollable.$.scrollHeight < scrollable.$.clientHeight) {
+ scrollable.setStyle('overflow-y', 'hidden');
+ } else {
+ scrollable.removeStyle('overflow-y');
+ }
+ },
+ null,
+ null,
+ 10000,
+ );
}
});
}
@@ -146,9 +156,17 @@
// Find the "Source" button, if any, and replace it with "Sourcedialog".
// (The 'sourcearea' plugin only works in CKEditor's iframe mode.)
let sourceButtonFound = false;
- for (let i = 0; !sourceButtonFound && i < settings.toolbar.length; i++) {
+ for (
+ let i = 0;
+ !sourceButtonFound && i < settings.toolbar.length;
+ i++
+ ) {
if (settings.toolbar[i] !== '/') {
- for (let j = 0; !sourceButtonFound && j < settings.toolbar[i].items.length; j++) {
+ for (
+ let j = 0;
+ !sourceButtonFound && j < settings.toolbar[i].items.length;
+ j++
+ ) {
if (settings.toolbar[i].items[j] === 'Source') {
sourceButtonFound = true;
// Swap sourcearea's "Source" button for sourcedialog's.
@@ -182,17 +200,19 @@
const externalPlugins = format.editorSettings.drupalExternalPlugins;
// Register and load additional CKEditor plugins as necessary.
if (externalPlugins) {
- Object.keys(externalPlugins || {}).forEach((pluginName) => {
- CKEDITOR.plugins.addExternal(pluginName, externalPlugins[pluginName], '');
+ Object.keys(externalPlugins || {}).forEach(pluginName => {
+ CKEDITOR.plugins.addExternal(
+ pluginName,
+ externalPlugins[pluginName],
+ '',
+ );
});
delete format.editorSettings.drupalExternalPlugins;
}
},
-
};
Drupal.ckeditor = {
-
/**
* Variable storing the current dialog's save callback.
*
@@ -226,18 +246,29 @@
}
// Remove any previous loading indicator.
- $target.css('position', 'relative').find('.ckeditor-dialog-loading').remove();
+ $target
+ .css('position', 'relative')
+ .find('.ckeditor-dialog-loading')
+ .remove();
// Add a consistent dialog class.
- const classes = dialogSettings.dialogClass ? dialogSettings.dialogClass.split(' ') : [];
+ const classes = dialogSettings.dialogClass
+ ? dialogSettings.dialogClass.split(' ')
+ : [];
classes.push('ui-dialog--narrow');
dialogSettings.dialogClass = classes.join(' ');
- dialogSettings.autoResize = window.matchMedia('(min-width: 600px)').matches;
+ dialogSettings.autoResize = window.matchMedia(
+ '(min-width: 600px)',
+ ).matches;
dialogSettings.width = 'auto';
// Add a "Loading…" message, hide it underneath the CKEditor toolbar,
// create a Drupal.Ajax instance to load the dialog and trigger it.
- const $content = $(`<div class="ckeditor-dialog-loading"><span style="top: -40px;" class="ckeditor-dialog-loading-link">${Drupal.t('Loading...')}</span></div>`);
+ const $content = $(
+ `<div class="ckeditor-dialog-loading"><span style="top: -40px;" class="ckeditor-dialog-loading-link">${Drupal.t(
+ 'Loading...',
+ )}</span></div>`,
+ );
$content.appendTo($target);
const ckeditorAjaxDialog = Drupal.ajax({
@@ -269,7 +300,7 @@
// Respond to new dialogs that are opened by CKEditor, closing the AJAX loader.
$(window).on('dialog:beforecreate', (e, dialog, $element, settings) => {
- $('.ckeditor-dialog-loading').animate({ top: '-40px' }, function () {
+ $('.ckeditor-dialog-loading').animate({ top: '-40px' }, function() {
$(this).remove();
});
});
@@ -290,7 +321,9 @@
// Formulate a default formula for the maximum autoGrow height.
$(document).on('drupalViewportOffsetChange', () => {
- CKEDITOR.config.autoGrow_maxHeight = 0.7 * (window.innerHeight - displace.offsets.top - displace.offsets.bottom);
+ CKEDITOR.config.autoGrow_maxHeight =
+ 0.7 *
+ (window.innerHeight - displace.offsets.top - displace.offsets.bottom);
});
// Redirect on hash change when the original hash has an associated CKEditor.
@@ -305,7 +338,10 @@
}
}
}
- $(window).on('hashchange.ckeditor', redirectTextareaFragmentToCKEditorInstance);
+ $(window).on(
+ 'hashchange.ckeditor',
+ redirectTextareaFragmentToCKEditorInstance,
+ );
// Set autoGrow to make the editor grow the moment it is created.
CKEDITOR.config.autoGrow_onStartup = true;
@@ -330,14 +366,25 @@
*
* @see http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document
*/
- AjaxCommands.prototype.ckeditor_add_stylesheet = function (ajax, response, status) {
+ AjaxCommands.prototype.ckeditor_add_stylesheet = function(
+ ajax,
+ response,
+ status,
+ ) {
const editor = CKEDITOR.instances[response.editor_id];
if (editor) {
- response.stylesheets.forEach((url) => {
+ response.stylesheets.forEach(url => {
editor.document.appendStyleSheet(url);
});
}
};
}
-}(Drupal, Drupal.debounce, CKEDITOR, jQuery, Drupal.displace, Drupal.AjaxCommands));
+})(
+ Drupal,
+ Drupal.debounce,
+ CKEDITOR,
+ jQuery,
+ Drupal.displace,
+ Drupal.AjaxCommands,
+);
diff --git a/core/modules/ckeditor/js/ckeditor.js b/core/modules/ckeditor/js/ckeditor.js
index 9a64450..cc12d73 100644
--- a/core/modules/ckeditor/js/ckeditor.js
+++ b/core/modules/ckeditor/js/ckeditor.js
@@ -15,7 +15,9 @@
};
var label = $('label[for=' + element.getAttribute('id') + ']').html();
- format.editorSettings.title = Drupal.t('Rich Text Editor, !label field', { '!label': label });
+ format.editorSettings.title = Drupal.t('Rich Text Editor, !label field', {
+ '!label': label
+ });
return !!CKEDITOR.replace(element, format.editorSettings);
},
diff --git a/core/modules/ckeditor/js/ckeditor.language.admin.es6.js b/core/modules/ckeditor/js/ckeditor.language.admin.es6.js
index f68dbd6..5019177 100644
--- a/core/modules/ckeditor/js/ckeditor.language.admin.es6.js
+++ b/core/modules/ckeditor/js/ckeditor.language.admin.es6.js
@@ -1,10 +1,14 @@
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Provides the summary for the "language" plugin settings vertical tab.
*/
Drupal.behaviors.ckeditorLanguageSettingsSummary = {
attach() {
- $('#edit-editor-settings-plugins-language').drupalSetSummary(context => $('#edit-editor-settings-plugins-language-language-list-type option:selected').text());
+ $('#edit-editor-settings-plugins-language').drupalSetSummary(context =>
+ $(
+ '#edit-editor-settings-plugins-language-language-list-type option:selected',
+ ).text(),
+ );
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/ckeditor/js/ckeditor.stylescombo.admin.es6.js b/core/modules/ckeditor/js/ckeditor.stylescombo.admin.es6.js
index 9fd145e..bfc0fda 100644
--- a/core/modules/ckeditor/js/ckeditor.stylescombo.admin.es6.js
+++ b/core/modules/ckeditor/js/ckeditor.stylescombo.admin.es6.js
@@ -3,7 +3,7 @@
* CKEditor StylesCombo admin behavior.
*/
-(function ($, Drupal, drupalSettings, _) {
+(function($, Drupal, drupalSettings, _) {
/**
* Ensures that the "stylescombo" button's metadata remains up-to-date.
*
@@ -30,10 +30,12 @@
const $ckeditorActiveToolbar = $context
.find('.ckeditor-toolbar-configuration')
.find('.ckeditor-toolbar-active');
- let previousStylesSet = drupalSettings.ckeditor.hiddenCKEditorConfig.stylesSet;
+ let previousStylesSet =
+ drupalSettings.ckeditor.hiddenCKEditorConfig.stylesSet;
const that = this;
- $context.find('[name="editor[settings][plugins][stylescombo][styles]"]')
- .on('blur.ckeditorStylesComboSettings', function () {
+ $context
+ .find('[name="editor[settings][plugins][stylescombo][styles]"]')
+ .on('blur.ckeditorStylesComboSettings', function() {
const styles = $.trim($(this).val());
const stylesSet = that._generateStylesSetSetting(styles);
if (!_.isEqual(previousStylesSet, stylesSet)) {
@@ -74,7 +76,10 @@
}
// Validate syntax: element[.class...]|label pattern expected.
- if (style.match(/^ *[a-zA-Z0-9]+ *(\.[a-zA-Z0-9_-]+ *)*\| *.+ *$/) === null) {
+ if (
+ style.match(/^ *[a-zA-Z0-9]+ *(\.[a-zA-Z0-9_-]+ *)*\| *.+ *$/) ===
+ null
+ ) {
// Instead of failing, we just ignore any invalid styles.
continue;
}
@@ -109,8 +114,12 @@
*/
Drupal.behaviors.ckeditorStylesComboSettingsSummary = {
attach() {
- $('[data-ckeditor-plugin-id="stylescombo"]').drupalSetSummary((context) => {
- const styles = $.trim($('[data-drupal-selector="edit-editor-settings-plugins-stylescombo-styles"]').val());
+ $('[data-ckeditor-plugin-id="stylescombo"]').drupalSetSummary(context => {
+ const styles = $.trim(
+ $(
+ '[data-drupal-selector="edit-editor-settings-plugins-stylescombo-styles"]',
+ ).val(),
+ );
if (styles.length === 0) {
return Drupal.t('No styles configured');
}
@@ -120,4 +129,4 @@
});
},
};
-}(jQuery, Drupal, drupalSettings, _));
+})(jQuery, Drupal, drupalSettings, _);
diff --git a/core/modules/ckeditor/js/models/Model.es6.js b/core/modules/ckeditor/js/models/Model.es6.js
index 40c0ac6..f0ad4cc 100644
--- a/core/modules/ckeditor/js/models/Model.es6.js
+++ b/core/modules/ckeditor/js/models/Model.es6.js
@@ -3,7 +3,7 @@
* A Backbone Model for the state of a CKEditor toolbar configuration .
*/
-(function (Drupal, Backbone) {
+(function(Drupal, Backbone) {
/**
* Backbone model for the CKEditor toolbar configuration state.
*
@@ -11,61 +11,63 @@
*
* @augments Backbone.Model
*/
- Drupal.ckeditor.Model = Backbone.Model.extend(/** @lends Drupal.ckeditor.Model# */{
-
- /**
- * Default values.
- *
- * @type {object}
- */
- defaults: /** @lends Drupal.ckeditor.Model# */{
-
+ Drupal.ckeditor.Model = Backbone.Model.extend(
+ /** @lends Drupal.ckeditor.Model# */ {
/**
- * The CKEditor configuration that is being manipulated through the UI.
+ * Default values.
+ *
+ * @type {object}
*/
- activeEditorConfig: null,
+ defaults: /** @lends Drupal.ckeditor.Model# */ {
+ /**
+ * The CKEditor configuration that is being manipulated through the UI.
+ */
+ activeEditorConfig: null,
- /**
- * The textarea that contains the serialized representation of the active
- * CKEditor configuration.
- */
- $textarea: null,
+ /**
+ * The textarea that contains the serialized representation of the active
+ * CKEditor configuration.
+ */
+ $textarea: null,
- /**
- * Tracks whether the active toolbar DOM structure has been changed. When
- * true, activeEditorConfig needs to be updated, and when that is updated,
- * $textarea will also be updated.
- */
- isDirty: false,
+ /**
+ * Tracks whether the active toolbar DOM structure has been changed. When
+ * true, activeEditorConfig needs to be updated, and when that is updated,
+ * $textarea will also be updated.
+ */
+ isDirty: false,
- /**
- * The configuration for the hidden CKEditor instance that is used to
- * build the features metadata.
- */
- hiddenEditorConfig: null,
+ /**
+ * The configuration for the hidden CKEditor instance that is used to
+ * build the features metadata.
+ */
+ hiddenEditorConfig: null,
- /**
- * A hash that maps buttons to features.
- */
- buttonsToFeatures: null,
+ /**
+ * A hash that maps buttons to features.
+ */
+ buttonsToFeatures: null,
- /**
- * A hash, keyed by a feature name, that details CKEditor plugin features.
- */
- featuresMetadata: null,
+ /**
+ * A hash, keyed by a feature name, that details CKEditor plugin features.
+ */
+ featuresMetadata: null,
+
+ /**
+ * Whether the button group names are currently visible.
+ */
+ groupNamesVisible: false,
+ },
/**
- * Whether the button group names are currently visible.
+ * @method
*/
- groupNamesVisible: false,
- },
-
- /**
- * @method
- */
- sync() {
- // Push the settings into the textarea.
- this.get('$textarea').val(JSON.stringify(this.get('activeEditorConfig')));
+ sync() {
+ // Push the settings into the textarea.
+ this.get('$textarea').val(
+ JSON.stringify(this.get('activeEditorConfig')),
+ );
+ },
},
- });
-}(Drupal, Backbone));
+ );
+})(Drupal, Backbone);
diff --git a/core/modules/ckeditor/js/plugins/drupalimage/plugin.es6.js b/core/modules/ckeditor/js/plugins/drupalimage/plugin.es6.js
index ec51244..4f37aa9 100644
--- a/core/modules/ckeditor/js/plugins/drupalimage/plugin.es6.js
+++ b/core/modules/ckeditor/js/plugins/drupalimage/plugin.es6.js
@@ -13,7 +13,7 @@
* @ignore
*/
-(function ($, Drupal, CKEDITOR) {
+(function($, Drupal, CKEDITOR) {
/**
* Gets the focused widget, if of the type specific for this plugin.
*
@@ -48,7 +48,7 @@
}
// Override default behaviour of 'drupalunlink' command.
- editor.getCommand('drupalunlink').on('exec', function (evt) {
+ editor.getCommand('drupalunlink').on('exec', function(evt) {
const widget = getFocusedWidget(editor);
// Override 'drupalunlink' only when link truly belongs to the widget. If
@@ -69,7 +69,7 @@
});
// Override default refresh of 'drupalunlink' command.
- editor.getCommand('drupalunlink').on('refresh', function (evt) {
+ editor.getCommand('drupalunlink').on('refresh', function(evt) {
const widget = getFocusedWidget(editor);
if (!widget) {
@@ -78,8 +78,11 @@
// Note that widget may be wrapped in a link, which
// does not belong to that widget (#11814).
- this.setState(widget.data.link || widget.wrapper.getAscendant('a') ?
- CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED);
+ this.setState(
+ widget.data.link || widget.wrapper.getAscendant('a')
+ ? CKEDITOR.TRISTATE_OFF
+ : CKEDITOR.TRISTATE_DISABLED,
+ );
evt.cancel();
});
@@ -93,7 +96,7 @@
beforeInit(editor) {
// Override the image2 widget definition to require and handle the
// additional data-entity-type and data-entity-uuid attributes.
- editor.on('widgetDefinition', (event) => {
+ editor.on('widgetDefinition', event => {
const widgetDefinition = event.data;
if (widgetDefinition.name !== 'image') {
return;
@@ -140,21 +143,29 @@
requiredContent.attributes['data-entity-type'] = '';
requiredContent.attributes['data-entity-uuid'] = '';
widgetDefinition.requiredContent = new CKEDITOR.style(requiredContent);
- widgetDefinition.allowedContent.img.attributes['!data-entity-type'] = true;
- widgetDefinition.allowedContent.img.attributes['!data-entity-uuid'] = true;
+ widgetDefinition.allowedContent.img.attributes[
+ '!data-entity-type'
+ ] = true;
+ widgetDefinition.allowedContent.img.attributes[
+ '!data-entity-uuid'
+ ] = true;
// Override downcast(): since we only accept <img> in our upcast method,
// the element is already correct. We only need to update the element's
// data-entity-uuid attribute.
- widgetDefinition.downcast = function (element) {
- element.attributes['data-entity-type'] = this.data['data-entity-type'];
- element.attributes['data-entity-uuid'] = this.data['data-entity-uuid'];
+ widgetDefinition.downcast = function(element) {
+ element.attributes['data-entity-type'] = this.data[
+ 'data-entity-type'
+ ];
+ element.attributes['data-entity-uuid'] = this.data[
+ 'data-entity-uuid'
+ ];
};
// We want to upcast <img> elements to a DOM structure required by the
// image2 widget; we only accept an <img> tag, and that <img> tag MAY
// have a data-entity-type and a data-entity-uuid attribute.
- widgetDefinition.upcast = function (element, data) {
+ widgetDefinition.upcast = function(element, data) {
if (element.name !== 'img') {
return;
}
@@ -182,9 +193,11 @@
// @see http://dev.ckeditor.com/ticket/13888
// @see https://www.drupal.org/node/2268941
const originalGetClasses = widgetDefinition.getClasses;
- widgetDefinition.getClasses = function () {
+ widgetDefinition.getClasses = function() {
const classes = originalGetClasses.call(this);
- const captionedClasses = (this.editor.config.image2_captionedClass || '').split(/\s+/);
+ const captionedClasses = (
+ this.editor.config.image2_captionedClass || ''
+ ).split(/\s+/);
if (captionedClasses.length && classes) {
for (let i = 0; i < captionedClasses.length; i++) {
@@ -212,20 +225,20 @@
// Protected; transforms widget's data object to the format used by the
// \Drupal\editor\Form\EditorImageDialog dialog, keeping only the data
// listed in widgetDefinition._dataForDialog.
- widgetDefinition._dataToDialogValues = function (data) {
+ widgetDefinition._dataToDialogValues = function(data) {
const dialogValues = {};
const map = widgetDefinition._mapDataToDialog;
- Object.keys(widgetDefinition._mapDataToDialog).forEach((key) => {
+ Object.keys(widgetDefinition._mapDataToDialog).forEach(key => {
dialogValues[map[key]] = data[key];
});
return dialogValues;
};
// Protected; the inverse of _dataToDialogValues.
- widgetDefinition._dialogValuesToData = function (dialogReturnValues) {
+ widgetDefinition._dialogValuesToData = function(dialogReturnValues) {
const data = {};
const map = widgetDefinition._mapDataToDialog;
- Object.keys(widgetDefinition._mapDataToDialog).forEach((key) => {
+ Object.keys(widgetDefinition._mapDataToDialog).forEach(key => {
if (dialogReturnValues.hasOwnProperty(map[key])) {
data[key] = dialogReturnValues[map[key]];
}
@@ -234,8 +247,8 @@
};
// Protected; creates Drupal dialog save callback.
- widgetDefinition._createDialogSaveCallback = function (editor, widget) {
- return function (dialogReturnValues) {
+ widgetDefinition._createDialogSaveCallback = function(editor, widget) {
+ return function(dialogReturnValues) {
const firstEdit = !widget.ready;
// Dialog may have blurred the widget. Re-focus it first.
@@ -252,7 +265,9 @@
// Set the updated widget data, after the necessary conversions from
// the dialog's return values.
// Note: on widget#setData this widget instance might be destroyed.
- const data = widgetDefinition._dialogValuesToData(dialogReturnValues.attributes);
+ const data = widgetDefinition._dialogValuesToData(
+ dialogReturnValues.attributes,
+ );
widget.setData(data);
// Retrieve the widget once again. It could've been destroyed
@@ -279,14 +294,20 @@
};
const originalInit = widgetDefinition.init;
- widgetDefinition.init = function () {
+ widgetDefinition.init = function() {
originalInit.call(this);
// Update data.link object with attributes if the link has been
// discovered.
// @see plugins/image2/plugin.js/init() in CKEditor; this is similar.
if (this.parts.link) {
- this.setData('link', CKEDITOR.plugins.image2.getLinkAttributesParser()(editor, this.parts.link));
+ this.setData(
+ 'link',
+ CKEDITOR.plugins.image2.getLinkAttributesParser()(
+ editor,
+ this.parts.link,
+ ),
+ );
}
};
});
@@ -295,14 +316,14 @@
// to handle its editing with a Drupal-native dialog.
// This includes also a case just after the image was created
// and dialog should be opened for it for the first time.
- editor.widgets.on('instanceCreated', (event) => {
+ editor.widgets.on('instanceCreated', event => {
const widget = event.data;
if (widget.name !== 'image') {
return;
}
- widget.on('edit', (event) => {
+ widget.on('edit', event => {
// Cancel edit event to break image2's dialog binding
// (and also to prevent automatic insertion before opening dialog).
event.cancel();
@@ -310,11 +331,16 @@
// Open drupalimage dialog.
editor.execCommand('editdrupalimage', {
existingValues: widget.definition._dataToDialogValues(widget.data),
- saveCallback: widget.definition._createDialogSaveCallback(editor, widget),
+ saveCallback: widget.definition._createDialogSaveCallback(
+ editor,
+ widget,
+ ),
// Drupal.t() will not work inside CKEditor plugins because CKEditor
// loads the JavaScript file instead of Drupal. Pull translated
// strings from the plugin settings that are translated server-side.
- dialogTitle: widget.data.src ? editor.config.drupalImage_dialogTitleEdit : editor.config.drupalImage_dialogTitleAdd,
+ dialogTitle: widget.data.src
+ ? editor.config.drupalImage_dialogTitleEdit
+ : editor.config.drupalImage_dialogTitleAdd,
});
});
});
@@ -322,7 +348,8 @@
// Register the "editdrupalimage" command, which essentially just replaces
// the "image" command's CKEditor dialog with a Drupal-native dialog.
editor.addCommand('editdrupalimage', {
- allowedContent: 'img[alt,!src,width,height,!data-entity-type,!data-entity-uuid]',
+ allowedContent:
+ 'img[alt,!src,width,height,!data-entity-type,!data-entity-uuid]',
requiredContent: 'img[alt,src,data-entity-type,data-entity-uuid]',
modes: { wysiwyg: 1 },
canUndo: true,
@@ -331,7 +358,13 @@
title: data.dialogTitle,
dialogClass: 'editor-image-dialog',
};
- Drupal.ckeditor.openDialog(editor, Drupal.url(`editor/dialog/image/${editor.config.drupal.format}`), data.existingValues, data.saveCallback, dialogSettings);
+ Drupal.ckeditor.openDialog(
+ editor,
+ Drupal.url(`editor/dialog/image/${editor.config.drupal.format}`),
+ data.existingValues,
+ data.saveCallback,
+ dialogSettings,
+ );
},
});
@@ -348,15 +381,14 @@
afterInit(editor) {
linkCommandIntegrator(editor);
},
-
});
// Override image2's integration with the official CKEditor link plugin:
// integrate with the drupallink plugin instead.
- CKEDITOR.plugins.image2.getLinkAttributesParser = function () {
+ CKEDITOR.plugins.image2.getLinkAttributesParser = function() {
return CKEDITOR.plugins.drupallink.parseLinkAttributes;
};
- CKEDITOR.plugins.image2.getLinkAttributesGetter = function () {
+ CKEDITOR.plugins.image2.getLinkAttributesGetter = function() {
return CKEDITOR.plugins.drupallink.getLinkAttributes;
};
@@ -364,4 +396,4 @@
CKEDITOR.plugins.drupalimage = {
getFocusedWidget,
};
-}(jQuery, Drupal, CKEDITOR));
+})(jQuery, Drupal, CKEDITOR);
diff --git a/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js b/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js
index 6b6a09e..1e63c4b 100644
--- a/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js
+++ b/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js
@@ -10,7 +10,7 @@
* @ignore
*/
-(function (CKEDITOR) {
+(function(CKEDITOR) {
/**
* Finds an element by its name.
*
@@ -31,7 +31,7 @@
}
let found = null;
- element.forEach((el) => {
+ element.forEach(el => {
if (el.name === name) {
found = el;
// Stop here.
@@ -53,227 +53,270 @@
// Drupal.t() will not work inside CKEditor plugins because CKEditor loads
// the JavaScript file instead of Drupal. Pull translated strings from the
// plugin settings that are translated server-side.
- const placeholderText = editor.config.drupalImageCaption_captionPlaceholderText;
+ const placeholderText =
+ editor.config.drupalImageCaption_captionPlaceholderText;
// Override the image2 widget definition to handle the additional
// data-align and data-caption attributes.
- editor.on('widgetDefinition', (event) => {
- const widgetDefinition = event.data;
- if (widgetDefinition.name !== 'image') {
- return;
- }
+ editor.on(
+ 'widgetDefinition',
+ event => {
+ const widgetDefinition = event.data;
+ if (widgetDefinition.name !== 'image') {
+ return;
+ }
- // Only perform the downcasting/upcasting for to the enabled filters.
- const captionFilterEnabled = editor.config.drupalImageCaption_captionFilterEnabled;
- const alignFilterEnabled = editor.config.drupalImageCaption_alignFilterEnabled;
-
- // Override default features definitions for drupalimagecaption.
- CKEDITOR.tools.extend(widgetDefinition.features, {
- caption: {
- requiredContent: 'img[data-caption]',
- },
- align: {
- requiredContent: 'img[data-align]',
- },
- }, true);
-
- // Extend requiredContent & allowedContent.
- // CKEDITOR.style is an immutable object: we cannot modify its
- // definition to extend requiredContent. Hence we get the definition,
- // modify it, and pass it to a new CKEDITOR.style instance.
- const requiredContent = widgetDefinition.requiredContent.getDefinition();
- requiredContent.attributes['data-align'] = '';
- requiredContent.attributes['data-caption'] = '';
- widgetDefinition.requiredContent = new CKEDITOR.style(requiredContent);
- widgetDefinition.allowedContent.img.attributes['!data-align'] = true;
- widgetDefinition.allowedContent.img.attributes['!data-caption'] = true;
-
- // Override allowedContent setting for the 'caption' nested editable.
- // This must match what caption_filter enforces.
- // @see \Drupal\filter\Plugin\Filter\FilterCaption::process()
- // @see \Drupal\Component\Utility\Xss::filter()
- widgetDefinition.editables.caption.allowedContent = 'a[!href]; em strong cite code br';
-
- // Override downcast(): ensure we *only* output <img>, but also ensure
- // we include the data-entity-type, data-entity-uuid, data-align and
- // data-caption attributes.
- const originalDowncast = widgetDefinition.downcast;
- widgetDefinition.downcast = function (element) {
- const img = findElementByName(element, 'img');
- originalDowncast.call(this, img);
-
- const caption = this.editables.caption;
- const captionHtml = caption && caption.getData();
- const attrs = img.attributes;
-
- if (captionFilterEnabled) {
- // If image contains a non-empty caption, serialize caption to the
- // data-caption attribute.
- if (captionHtml) {
- attrs['data-caption'] = captionHtml;
+ // Only perform the downcasting/upcasting for to the enabled filters.
+ const captionFilterEnabled =
+ editor.config.drupalImageCaption_captionFilterEnabled;
+ const alignFilterEnabled =
+ editor.config.drupalImageCaption_alignFilterEnabled;
+
+ // Override default features definitions for drupalimagecaption.
+ CKEDITOR.tools.extend(
+ widgetDefinition.features,
+ {
+ caption: {
+ requiredContent: 'img[data-caption]',
+ },
+ align: {
+ requiredContent: 'img[data-align]',
+ },
+ },
+ true,
+ );
+
+ // Extend requiredContent & allowedContent.
+ // CKEDITOR.style is an immutable object: we cannot modify its
+ // definition to extend requiredContent. Hence we get the definition,
+ // modify it, and pass it to a new CKEDITOR.style instance.
+ const requiredContent = widgetDefinition.requiredContent.getDefinition();
+ requiredContent.attributes['data-align'] = '';
+ requiredContent.attributes['data-caption'] = '';
+ widgetDefinition.requiredContent = new CKEDITOR.style(
+ requiredContent,
+ );
+ widgetDefinition.allowedContent.img.attributes['!data-align'] = true;
+ widgetDefinition.allowedContent.img.attributes[
+ '!data-caption'
+ ] = true;
+
+ // Override allowedContent setting for the 'caption' nested editable.
+ // This must match what caption_filter enforces.
+ // @see \Drupal\filter\Plugin\Filter\FilterCaption::process()
+ // @see \Drupal\Component\Utility\Xss::filter()
+ widgetDefinition.editables.caption.allowedContent =
+ 'a[!href]; em strong cite code br';
+
+ // Override downcast(): ensure we *only* output <img>, but also ensure
+ // we include the data-entity-type, data-entity-uuid, data-align and
+ // data-caption attributes.
+ const originalDowncast = widgetDefinition.downcast;
+ widgetDefinition.downcast = function(element) {
+ const img = findElementByName(element, 'img');
+ originalDowncast.call(this, img);
+
+ const caption = this.editables.caption;
+ const captionHtml = caption && caption.getData();
+ const attrs = img.attributes;
+
+ if (captionFilterEnabled) {
+ // If image contains a non-empty caption, serialize caption to the
+ // data-caption attribute.
+ if (captionHtml) {
+ attrs['data-caption'] = captionHtml;
+ }
}
- }
- if (alignFilterEnabled) {
- if (this.data.align !== 'none') {
- attrs['data-align'] = this.data.align;
+ if (alignFilterEnabled) {
+ if (this.data.align !== 'none') {
+ attrs['data-align'] = this.data.align;
+ }
}
- }
- // If img is wrapped with a link, we want to return that link.
- if (img.parent.name === 'a') {
- return img.parent;
- }
+ // If img is wrapped with a link, we want to return that link.
+ if (img.parent.name === 'a') {
+ return img.parent;
+ }
- return img;
- };
-
- // We want to upcast <img> elements to a DOM structure required by the
- // image2 widget. Depending on a case it may be:
- // - just an <img> tag (non-captioned, not-centered image),
- // - <img> tag in a paragraph (non-captioned, centered image),
- // - <figure> tag (captioned image).
- // We take the same attributes into account as downcast() does.
- const originalUpcast = widgetDefinition.upcast;
- widgetDefinition.upcast = function (element, data) {
- if (element.name !== 'img' || !element.attributes['data-entity-type'] || !element.attributes['data-entity-uuid']) {
- return;
- }
- // Don't initialize on pasted fake objects.
- if (element.attributes['data-cke-realelement']) {
- return;
- }
+ return img;
+ };
- element = originalUpcast.call(this, element, data);
- const attrs = element.attributes;
+ // We want to upcast <img> elements to a DOM structure required by the
+ // image2 widget. Depending on a case it may be:
+ // - just an <img> tag (non-captioned, not-centered image),
+ // - <img> tag in a paragraph (non-captioned, centered image),
+ // - <figure> tag (captioned image).
+ // We take the same attributes into account as downcast() does.
+ const originalUpcast = widgetDefinition.upcast;
+ widgetDefinition.upcast = function(element, data) {
+ if (
+ element.name !== 'img' ||
+ !element.attributes['data-entity-type'] ||
+ !element.attributes['data-entity-uuid']
+ ) {
+ return;
+ }
+ // Don't initialize on pasted fake objects.
+ if (element.attributes['data-cke-realelement']) {
+ return;
+ }
- if (element.parent.name === 'a') {
- element = element.parent;
- }
+ element = originalUpcast.call(this, element, data);
+ const attrs = element.attributes;
- let retElement = element;
- let caption;
+ if (element.parent.name === 'a') {
+ element = element.parent;
+ }
- // We won't need the attributes during editing: we'll use widget.data
- // to store them (except the caption, which is stored in the DOM).
- if (captionFilterEnabled) {
- caption = attrs['data-caption'];
- delete attrs['data-caption'];
- }
- if (alignFilterEnabled) {
- data.align = attrs['data-align'];
- delete attrs['data-align'];
- }
- data['data-entity-type'] = attrs['data-entity-type'];
- delete attrs['data-entity-type'];
- data['data-entity-uuid'] = attrs['data-entity-uuid'];
- delete attrs['data-entity-uuid'];
-
- if (captionFilterEnabled) {
- // Unwrap from <p> wrapper created by HTML parser for a captioned
- // image. The captioned image will be transformed to <figure>, so we
- // don't want the <p> anymore.
- if (element.parent.name === 'p' && caption) {
- let index = element.getIndex();
- const splitBefore = index > 0;
- const splitAfter = index + 1 < element.parent.children.length;
-
- if (splitBefore) {
- element.parent.split(index);
- }
- index = element.getIndex();
- if (splitAfter) {
- element.parent.split(index + 1);
- }
+ let retElement = element;
+ let caption;
- element.parent.replaceWith(element);
- retElement = element;
+ // We won't need the attributes during editing: we'll use widget.data
+ // to store them (except the caption, which is stored in the DOM).
+ if (captionFilterEnabled) {
+ caption = attrs['data-caption'];
+ delete attrs['data-caption'];
}
-
- // If this image has a caption, create a full <figure> structure.
- if (caption) {
- const figure = new CKEDITOR.htmlParser.element('figure');
- caption = new CKEDITOR.htmlParser.fragment.fromHtml(caption, 'figcaption');
-
- // Use Drupal's data-placeholder attribute to insert a CSS-based,
- // translation-ready placeholder for empty captions. Note that it
- // also must to be done for new instances (see
- // widgetDefinition._createDialogSaveCallback).
- caption.attributes['data-placeholder'] = placeholderText;
-
- element.replaceWith(figure);
- figure.add(element);
- figure.add(caption);
- figure.attributes.class = editor.config.image2_captionedClass;
- retElement = figure;
+ if (alignFilterEnabled) {
+ data.align = attrs['data-align'];
+ delete attrs['data-align'];
}
- }
+ data['data-entity-type'] = attrs['data-entity-type'];
+ delete attrs['data-entity-type'];
+ data['data-entity-uuid'] = attrs['data-entity-uuid'];
+ delete attrs['data-entity-uuid'];
+
+ if (captionFilterEnabled) {
+ // Unwrap from <p> wrapper created by HTML parser for a captioned
+ // image. The captioned image will be transformed to <figure>, so we
+ // don't want the <p> anymore.
+ if (element.parent.name === 'p' && caption) {
+ let index = element.getIndex();
+ const splitBefore = index > 0;
+ const splitAfter = index + 1 < element.parent.children.length;
+
+ if (splitBefore) {
+ element.parent.split(index);
+ }
+ index = element.getIndex();
+ if (splitAfter) {
+ element.parent.split(index + 1);
+ }
+
+ element.parent.replaceWith(element);
+ retElement = element;
+ }
- if (alignFilterEnabled) {
- // If this image doesn't have a caption (or the caption filter is
- // disabled), but it is centered, make sure that it's wrapped with
- // <p>, which will become a part of the widget.
- if (data.align === 'center' && (!captionFilterEnabled || !caption)) {
- const p = new CKEDITOR.htmlParser.element('p');
- element.replaceWith(p);
- p.add(element);
- // Apply the class for centered images.
- p.addClass(editor.config.image2_alignClasses[1]);
- retElement = p;
+ // If this image has a caption, create a full <figure> structure.
+ if (caption) {
+ const figure = new CKEDITOR.htmlParser.element('figure');
+ caption = new CKEDITOR.htmlParser.fragment.fromHtml(
+ caption,
+ 'figcaption',
+ );
+
+ // Use Drupal's data-placeholder attribute to insert a CSS-based,
+ // translation-ready placeholder for empty captions. Note that it
+ // also must to be done for new instances (see
+ // widgetDefinition._createDialogSaveCallback).
+ caption.attributes['data-placeholder'] = placeholderText;
+
+ element.replaceWith(figure);
+ figure.add(element);
+ figure.add(caption);
+ figure.attributes.class = editor.config.image2_captionedClass;
+ retElement = figure;
+ }
}
- }
- // Return the upcasted element (<img>, <figure> or <p>).
- return retElement;
- };
-
- // Protected; keys of the widget data to be sent to the Drupal dialog.
- // Append to the values defined by the drupalimage plugin.
- // @see core/modules/ckeditor/js/plugins/drupalimage/plugin.js
- CKEDITOR.tools.extend(widgetDefinition._mapDataToDialog, {
- align: 'data-align',
- 'data-caption': 'data-caption',
- hasCaption: 'hasCaption',
- });
-
- // Override Drupal dialog save callback.
- const originalCreateDialogSaveCallback = widgetDefinition._createDialogSaveCallback;
- widgetDefinition._createDialogSaveCallback = function (editor, widget) {
- const saveCallback = originalCreateDialogSaveCallback.call(this, editor, widget);
-
- return function (dialogReturnValues) {
- // Ensure hasCaption is a boolean. image2 assumes it always works
- // with booleans; if this is not the case, then
- // CKEDITOR.plugins.image2.stateShifter() will incorrectly mark
- // widget.data.hasCaption as "changed" (e.g. when hasCaption === 0
- // instead of hasCaption === false). This causes image2's "state
- // shifter" to enter the wrong branch of the algorithm and blow up.
- dialogReturnValues.attributes.hasCaption = !!dialogReturnValues.attributes.hasCaption;
-
- const actualWidget = saveCallback(dialogReturnValues);
-
- // By default, the template of captioned widget has no
- // data-placeholder attribute. Note that it also must be done when
- // upcasting existing elements (see widgetDefinition.upcast).
- if (dialogReturnValues.attributes.hasCaption) {
- actualWidget.editables.caption.setAttribute('data-placeholder', placeholderText);
-
- // Some browsers will add a <br> tag to a newly created DOM
- // element with no content. Remove this <br> if it is the only
- // thing in the caption. Our placeholder support requires the
- // element be entirely empty. See filter-caption.css.
- const captionElement = actualWidget.editables.caption.$;
- if (captionElement.childNodes.length === 1 && captionElement.childNodes.item(0).nodeName === 'BR') {
- captionElement.removeChild(captionElement.childNodes.item(0));
+ if (alignFilterEnabled) {
+ // If this image doesn't have a caption (or the caption filter is
+ // disabled), but it is centered, make sure that it's wrapped with
+ // <p>, which will become a part of the widget.
+ if (
+ data.align === 'center' &&
+ (!captionFilterEnabled || !caption)
+ ) {
+ const p = new CKEDITOR.htmlParser.element('p');
+ element.replaceWith(p);
+ p.add(element);
+ // Apply the class for centered images.
+ p.addClass(editor.config.image2_alignClasses[1]);
+ retElement = p;
}
}
+
+ // Return the upcasted element (<img>, <figure> or <p>).
+ return retElement;
+ };
+
+ // Protected; keys of the widget data to be sent to the Drupal dialog.
+ // Append to the values defined by the drupalimage plugin.
+ // @see core/modules/ckeditor/js/plugins/drupalimage/plugin.js
+ CKEDITOR.tools.extend(widgetDefinition._mapDataToDialog, {
+ align: 'data-align',
+ 'data-caption': 'data-caption',
+ hasCaption: 'hasCaption',
+ });
+
+ // Override Drupal dialog save callback.
+ const originalCreateDialogSaveCallback =
+ widgetDefinition._createDialogSaveCallback;
+ widgetDefinition._createDialogSaveCallback = function(
+ editor,
+ widget,
+ ) {
+ const saveCallback = originalCreateDialogSaveCallback.call(
+ this,
+ editor,
+ widget,
+ );
+
+ return function(dialogReturnValues) {
+ // Ensure hasCaption is a boolean. image2 assumes it always works
+ // with booleans; if this is not the case, then
+ // CKEDITOR.plugins.image2.stateShifter() will incorrectly mark
+ // widget.data.hasCaption as "changed" (e.g. when hasCaption === 0
+ // instead of hasCaption === false). This causes image2's "state
+ // shifter" to enter the wrong branch of the algorithm and blow up.
+ dialogReturnValues.attributes.hasCaption = !!dialogReturnValues
+ .attributes.hasCaption;
+
+ const actualWidget = saveCallback(dialogReturnValues);
+
+ // By default, the template of captioned widget has no
+ // data-placeholder attribute. Note that it also must be done when
+ // upcasting existing elements (see widgetDefinition.upcast).
+ if (dialogReturnValues.attributes.hasCaption) {
+ actualWidget.editables.caption.setAttribute(
+ 'data-placeholder',
+ placeholderText,
+ );
+
+ // Some browsers will add a <br> tag to a newly created DOM
+ // element with no content. Remove this <br> if it is the only
+ // thing in the caption. Our placeholder support requires the
+ // element be entirely empty. See filter-caption.css.
+ const captionElement = actualWidget.editables.caption.$;
+ if (
+ captionElement.childNodes.length === 1 &&
+ captionElement.childNodes.item(0).nodeName === 'BR'
+ ) {
+ captionElement.removeChild(captionElement.childNodes.item(0));
+ }
+ }
+ };
};
- };
- // Low priority to ensure drupalimage's event handler runs first.
- }, null, null, 20);
+ // Low priority to ensure drupalimage's event handler runs first.
+ },
+ null,
+ null,
+ 20,
+ );
},
afterInit(editor) {
- const disableButtonIfOnWidget = function (evt) {
+ const disableButtonIfOnWidget = function(evt) {
const widget = editor.widgets.focused;
if (widget && widget.name === 'image') {
this.setState(CKEDITOR.TRISTATE_DISABLED);
@@ -282,9 +325,17 @@
};
// Disable alignment buttons if the align filter is not enabled.
- if (editor.plugins.justify && !editor.config.drupalImageCaption_alignFilterEnabled) {
+ if (
+ editor.plugins.justify &&
+ !editor.config.drupalImageCaption_alignFilterEnabled
+ ) {
let cmd;
- const commands = ['justifyleft', 'justifycenter', 'justifyright', 'justifyblock'];
+ const commands = [
+ 'justifyleft',
+ 'justifycenter',
+ 'justifyright',
+ 'justifyblock',
+ ];
for (let n = 0; n < commands.length; n++) {
cmd = editor.getCommand(commands[n]);
cmd.contextSensitive = 1;
@@ -293,4 +344,4 @@
}
},
});
-}(CKEDITOR));
+})(CKEDITOR);
diff --git a/core/modules/ckeditor/js/plugins/drupallink/plugin.es6.js b/core/modules/ckeditor/js/plugins/drupallink/plugin.es6.js
index 42b8565..7df1b8a 100644
--- a/core/modules/ckeditor/js/plugins/drupallink/plugin.es6.js
+++ b/core/modules/ckeditor/js/plugins/drupallink/plugin.es6.js
@@ -5,14 +5,18 @@
* @ignore
*/
-(function ($, Drupal, drupalSettings, CKEDITOR) {
+(function($, Drupal, drupalSettings, CKEDITOR) {
function parseAttributes(editor, element) {
const parsedAttributes = {};
const domElement = element.$;
let attribute;
let attributeName;
- for (let attrIndex = 0; attrIndex < domElement.attributes.length; attrIndex++) {
+ for (
+ let attrIndex = 0;
+ attrIndex < domElement.attributes.length;
+ attrIndex++
+ ) {
attribute = domElement.attributes.item(attrIndex);
attributeName = attribute.nodeName.toLowerCase();
// Ignore data-cke-* attributes; they're CKEditor internals.
@@ -21,12 +25,15 @@
}
// Store the value for this attribute, unless there's a data-cke-saved-
// alternative for it, which will contain the quirk-free, original value.
- parsedAttributes[attributeName] = element.data(`cke-saved-${attributeName}`) || attribute.nodeValue;
+ parsedAttributes[attributeName] =
+ element.data(`cke-saved-${attributeName}`) || attribute.nodeValue;
}
// Remove any cke_* classes.
if (parsedAttributes.class) {
- parsedAttributes.class = CKEDITOR.tools.trim(parsedAttributes.class.replace(/cke_\S+/, ''));
+ parsedAttributes.class = CKEDITOR.tools.trim(
+ parsedAttributes.class.replace(/cke_\S+/, ''),
+ );
}
return parsedAttributes;
@@ -34,7 +41,7 @@
function getAttributes(editor, data) {
const set = {};
- Object.keys(data || {}).forEach((attributeName) => {
+ Object.keys(data || {}).forEach(attributeName => {
set[attributeName] = data[attributeName];
});
@@ -44,7 +51,7 @@
// Remove all attributes which are not currently set.
const removed = {};
- Object.keys(set).forEach((s) => {
+ Object.keys(set).forEach(s => {
delete removed[s];
});
@@ -115,7 +122,8 @@
canUndo: true,
exec(editor) {
const drupalImageUtils = CKEDITOR.plugins.drupalimage;
- const focusedImageWidget = drupalImageUtils && drupalImageUtils.getFocusedWidget(editor);
+ const focusedImageWidget =
+ drupalImageUtils && drupalImageUtils.getFocusedWidget(editor);
let linkElement = getSelectedLink(editor);
// Set existing values based on selected element.
@@ -130,11 +138,17 @@
}
// Prepare a save callback to be used upon saving the dialog.
- const saveCallback = function (returnValues) {
+ const saveCallback = function(returnValues) {
// If an image widget is focused, we're not editing an independent
// link, but we're wrapping an image widget in a link.
if (focusedImageWidget) {
- focusedImageWidget.setData('link', CKEDITOR.tools.extend(returnValues.attributes, focusedImageWidget.data.link));
+ focusedImageWidget.setData(
+ 'link',
+ CKEDITOR.tools.extend(
+ returnValues.attributes,
+ focusedImageWidget.data.link,
+ ),
+ );
editor.fire('saveSnapshot');
return;
}
@@ -149,13 +163,19 @@
// Use link URL as text with a collapsed cursor.
if (range.collapsed) {
// Shorten mailto URLs to just the email address.
- const text = new CKEDITOR.dom.text(returnValues.attributes.href.replace(/^mailto:/, ''), editor.document);
+ const text = new CKEDITOR.dom.text(
+ returnValues.attributes.href.replace(/^mailto:/, ''),
+ editor.document,
+ );
range.insertNode(text);
range.selectNodeContents(text);
}
// Create the new link by applying a style to the new text.
- const style = new CKEDITOR.style({ element: 'a', attributes: returnValues.attributes });
+ const style = new CKEDITOR.style({
+ element: 'a',
+ attributes: returnValues.attributes,
+ });
style.type = CKEDITOR.STYLE_INLINE;
style.applyToRange(range);
range.select();
@@ -165,7 +185,7 @@
}
// Update the link properties.
else if (linkElement) {
- Object.keys(returnValues.attributes || {}).forEach((attrName) => {
+ Object.keys(returnValues.attributes || {}).forEach(attrName => {
// Update the property if a value is specified.
if (returnValues.attributes[attrName].length > 0) {
const value = returnValues.attributes[attrName];
@@ -186,12 +206,20 @@
// loads the JavaScript file instead of Drupal. Pull translated
// strings from the plugin settings that are translated server-side.
const dialogSettings = {
- title: linkElement ? editor.config.drupalLink_dialogTitleEdit : editor.config.drupalLink_dialogTitleAdd,
+ title: linkElement
+ ? editor.config.drupalLink_dialogTitleEdit
+ : editor.config.drupalLink_dialogTitleAdd,
dialogClass: 'editor-link-dialog',
};
// Open the dialog for the edit form.
- Drupal.ckeditor.openDialog(editor, Drupal.url(`editor/dialog/link/${editor.config.drupal.format}`), existingValues, saveCallback, dialogSettings);
+ Drupal.ckeditor.openDialog(
+ editor,
+ Drupal.url(`editor/dialog/link/${editor.config.drupal.format}`),
+ existingValues,
+ saveCallback,
+ dialogSettings,
+ );
},
});
editor.addCommand('drupalunlink', {
@@ -204,15 +232,24 @@
},
}),
exec(editor) {
- const style = new CKEDITOR.style({ element: 'a', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 });
+ const style = new CKEDITOR.style({
+ element: 'a',
+ type: CKEDITOR.STYLE_INLINE,
+ alwaysRemoveElement: 1,
+ });
editor.removeStyle(style);
},
refresh(editor, path) {
- const element = path.lastElement && path.lastElement.getAscendant('a', true);
- if (element && element.getName() === 'a' && element.getAttribute('href') && element.getChildCount()) {
+ const element =
+ path.lastElement && path.lastElement.getAscendant('a', true);
+ if (
+ element &&
+ element.getName() === 'a' &&
+ element.getAttribute('href') &&
+ element.getChildCount()
+ ) {
this.setState(CKEDITOR.TRISTATE_OFF);
- }
- else {
+ } else {
this.setState(CKEDITOR.TRISTATE_DISABLED);
}
},
@@ -233,7 +270,7 @@
});
}
- editor.on('doubleclick', (evt) => {
+ editor.on('doubleclick', evt => {
const element = getSelectedLink(editor) || evt.data.element;
if (!element.isReadOnly()) {
@@ -276,7 +313,10 @@
let menu = {};
if (anchor.getAttribute('href') && anchor.getChildCount()) {
- menu = { link: CKEDITOR.TRISTATE_OFF, unlink: CKEDITOR.TRISTATE_OFF };
+ menu = {
+ link: CKEDITOR.TRISTATE_OFF,
+ unlink: CKEDITOR.TRISTATE_OFF,
+ };
}
return menu;
});
@@ -291,4 +331,4 @@
parseLinkAttributes: parseAttributes,
getLinkAttributes: getAttributes,
};
-}(jQuery, Drupal, drupalSettings, CKEDITOR));
+})(jQuery, Drupal, drupalSettings, CKEDITOR);
diff --git a/core/modules/ckeditor/js/plugins/drupallink/plugin.js b/core/modules/ckeditor/js/plugins/drupallink/plugin.js
index 3e5e0db..f8e2505 100644
--- a/core/modules/ckeditor/js/plugins/drupallink/plugin.js
+++ b/core/modules/ckeditor/js/plugins/drupallink/plugin.js
@@ -118,7 +118,10 @@
range.selectNodeContents(text);
}
- var style = new CKEDITOR.style({ element: 'a', attributes: returnValues.attributes });
+ var style = new CKEDITOR.style({
+ element: 'a',
+ attributes: returnValues.attributes
+ });
style.type = CKEDITOR.STYLE_INLINE;
style.applyToRange(range);
range.select();
@@ -157,7 +160,11 @@
}
}),
exec: function exec(editor) {
- var style = new CKEDITOR.style({ element: 'a', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 });
+ var style = new CKEDITOR.style({
+ element: 'a',
+ type: CKEDITOR.STYLE_INLINE,
+ alwaysRemoveElement: 1
+ });
editor.removeStyle(style);
},
refresh: function refresh(editor, path) {
@@ -224,7 +231,10 @@
var menu = {};
if (anchor.getAttribute('href') && anchor.getChildCount()) {
- menu = { link: CKEDITOR.TRISTATE_OFF, unlink: CKEDITOR.TRISTATE_OFF };
+ menu = {
+ link: CKEDITOR.TRISTATE_OFF,
+ unlink: CKEDITOR.TRISTATE_OFF
+ };
}
return menu;
});
diff --git a/core/modules/ckeditor/js/views/AuralView.es6.js b/core/modules/ckeditor/js/views/AuralView.es6.js
index 6702ae3..5d789ee 100644
--- a/core/modules/ckeditor/js/views/AuralView.es6.js
+++ b/core/modules/ckeditor/js/views/AuralView.es6.js
@@ -4,226 +4,263 @@
* configuration.
*/
-(function (Drupal, Backbone, $) {
- Drupal.ckeditor.AuralView = Backbone.View.extend(/** @lends Drupal.ckeditor.AuralView# */{
+(function(Drupal, Backbone, $) {
+ Drupal.ckeditor.AuralView = Backbone.View.extend(
+ /** @lends Drupal.ckeditor.AuralView# */ {
+ /**
+ * @type {object}
+ */
+ events: {
+ 'click .ckeditor-buttons a': 'announceButtonHelp',
+ 'click .ckeditor-multiple-buttons a': 'announceSeparatorHelp',
+ 'focus .ckeditor-button a': 'onFocus',
+ 'focus .ckeditor-button-separator a': 'onFocus',
+ 'focus .ckeditor-toolbar-group': 'onFocus',
+ },
- /**
- * @type {object}
- */
- events: {
- 'click .ckeditor-buttons a': 'announceButtonHelp',
- 'click .ckeditor-multiple-buttons a': 'announceSeparatorHelp',
- 'focus .ckeditor-button a': 'onFocus',
- 'focus .ckeditor-button-separator a': 'onFocus',
- 'focus .ckeditor-toolbar-group': 'onFocus',
- },
-
- /**
- * Backbone View for CKEditor toolbar configuration; aural UX (output only).
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- // Announce the button and group positions when the model is no longer
- // dirty.
- this.listenTo(this.model, 'change:isDirty', this.announceMove);
- },
+ /**
+ * Backbone View for CKEditor toolbar configuration; aural UX (output only).
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ // Announce the button and group positions when the model is no longer
+ // dirty.
+ this.listenTo(this.model, 'change:isDirty', this.announceMove);
+ },
- /**
- * Calls announce on buttons and groups when their position is changed.
- *
- * @param {Drupal.ckeditor.ConfigurationModel} model
- * The ckeditor configuration model.
- * @param {bool} isDirty
- * A model attribute that indicates if the changed toolbar configuration
- * has been stored or not.
- */
- announceMove(model, isDirty) {
- // Announce the position of a button or group after the model has been
- // updated.
- if (!isDirty) {
- const item = document.activeElement || null;
- if (item) {
- const $item = $(item);
- if ($item.hasClass('ckeditor-toolbar-group')) {
- this.announceButtonGroupPosition($item);
- }
- else if ($item.parent().hasClass('ckeditor-button')) {
- this.announceButtonPosition($item.parent());
+ /**
+ * Calls announce on buttons and groups when their position is changed.
+ *
+ * @param {Drupal.ckeditor.ConfigurationModel} model
+ * The ckeditor configuration model.
+ * @param {bool} isDirty
+ * A model attribute that indicates if the changed toolbar configuration
+ * has been stored or not.
+ */
+ announceMove(model, isDirty) {
+ // Announce the position of a button or group after the model has been
+ // updated.
+ if (!isDirty) {
+ const item = document.activeElement || null;
+ if (item) {
+ const $item = $(item);
+ if ($item.hasClass('ckeditor-toolbar-group')) {
+ this.announceButtonGroupPosition($item);
+ } else if ($item.parent().hasClass('ckeditor-button')) {
+ this.announceButtonPosition($item.parent());
+ }
}
}
- }
- },
-
- /**
- * Handles the focus event of elements in the active and available toolbars.
- *
- * @param {jQuery.Event} event
- * The focus event that was triggered.
- */
- onFocus(event) {
- event.stopPropagation();
+ },
- const $originalTarget = $(event.target);
- const $currentTarget = $(event.currentTarget);
- const $parent = $currentTarget.parent();
- if ($parent.hasClass('ckeditor-button') || $parent.hasClass('ckeditor-button-separator')) {
- this.announceButtonPosition($currentTarget.parent());
- }
- else if ($originalTarget.attr('role') !== 'button' && $currentTarget.hasClass('ckeditor-toolbar-group')) {
- this.announceButtonGroupPosition($currentTarget);
- }
- },
-
- /**
- * Announces the current position of a button group.
- *
- * @param {jQuery} $group
- * A jQuery set that contains an li element that wraps a group of buttons.
- */
- announceButtonGroupPosition($group) {
- const $groups = $group.parent().children();
- const $row = $group.closest('.ckeditor-row');
- const $rows = $row.parent().children();
- const position = $groups.index($group) + 1;
- const positionCount = $groups.not('.placeholder').length;
- const row = $rows.index($row) + 1;
- const rowCount = $rows.not('.placeholder').length;
- let text = Drupal.t('@groupName button group in position @position of @positionCount in row @row of @rowCount.', {
- '@groupName': $group.attr('data-drupal-ckeditor-toolbar-group-name'),
- '@position': position,
- '@positionCount': positionCount,
- '@row': row,
- '@rowCount': rowCount,
- });
- // If this position is the first in the last row then tell the user that
- // pressing the down arrow key will create a new row.
- if (position === 1 && row === rowCount) {
- text += '\n';
- text += Drupal.t('Press the down arrow key to create a new row.');
- }
- Drupal.announce(text, 'assertive');
- },
+ /**
+ * Handles the focus event of elements in the active and available toolbars.
+ *
+ * @param {jQuery.Event} event
+ * The focus event that was triggered.
+ */
+ onFocus(event) {
+ event.stopPropagation();
- /**
- * Announces current button position.
- *
- * @param {jQuery} $button
- * A jQuery set that contains an li element that wraps a button.
- */
- announceButtonPosition($button) {
- const $row = $button.closest('.ckeditor-row');
- const $rows = $row.parent().children();
- const $buttons = $button.closest('.ckeditor-buttons').children();
- const $group = $button.closest('.ckeditor-toolbar-group');
- const $groups = $group.parent().children();
- const groupPosition = $groups.index($group) + 1;
- const groupPositionCount = $groups.not('.placeholder').length;
- const position = $buttons.index($button) + 1;
- const positionCount = $buttons.length;
- const row = $rows.index($row) + 1;
- const rowCount = $rows.not('.placeholder').length;
- // The name of the button separator is 'button separator' and its type
- // is 'separator', so we do not want to print the type of this item,
- // otherwise the UA will speak 'button separator separator'.
- const type = ($button.attr('data-drupal-ckeditor-type') === 'separator') ? '' : Drupal.t('button');
- let text;
- // The button is located in the available button set.
- if ($button.closest('.ckeditor-toolbar-disabled').length > 0) {
- text = Drupal.t('@name @type.', {
- '@name': $button.children().attr('aria-label'),
- '@type': type,
- });
- text += `\n${Drupal.t('Press the down arrow key to activate.')}`;
+ const $originalTarget = $(event.target);
+ const $currentTarget = $(event.currentTarget);
+ const $parent = $currentTarget.parent();
+ if (
+ $parent.hasClass('ckeditor-button') ||
+ $parent.hasClass('ckeditor-button-separator')
+ ) {
+ this.announceButtonPosition($currentTarget.parent());
+ } else if (
+ $originalTarget.attr('role') !== 'button' &&
+ $currentTarget.hasClass('ckeditor-toolbar-group')
+ ) {
+ this.announceButtonGroupPosition($currentTarget);
+ }
+ },
- Drupal.announce(text, 'assertive');
- }
- // The button is in the active toolbar.
- else if ($group.not('.placeholder').length === 1) {
- text = Drupal.t('@name @type in position @position of @positionCount in @groupName button group in row @row of @rowCount.', {
- '@name': $button.children().attr('aria-label'),
- '@type': type,
- '@position': position,
- '@positionCount': positionCount,
- '@groupName': $group.attr('data-drupal-ckeditor-toolbar-group-name'),
- '@row': row,
- '@rowCount': rowCount,
- });
+ /**
+ * Announces the current position of a button group.
+ *
+ * @param {jQuery} $group
+ * A jQuery set that contains an li element that wraps a group of buttons.
+ */
+ announceButtonGroupPosition($group) {
+ const $groups = $group.parent().children();
+ const $row = $group.closest('.ckeditor-row');
+ const $rows = $row.parent().children();
+ const position = $groups.index($group) + 1;
+ const positionCount = $groups.not('.placeholder').length;
+ const row = $rows.index($row) + 1;
+ const rowCount = $rows.not('.placeholder').length;
+ let text = Drupal.t(
+ '@groupName button group in position @position of @positionCount in row @row of @rowCount.',
+ {
+ '@groupName': $group.attr(
+ 'data-drupal-ckeditor-toolbar-group-name',
+ ),
+ '@position': position,
+ '@positionCount': positionCount,
+ '@row': row,
+ '@rowCount': rowCount,
+ },
+ );
// If this position is the first in the last row then tell the user that
// pressing the down arrow key will create a new row.
- if (groupPosition === 1 && position === 1 && row === rowCount) {
+ if (position === 1 && row === rowCount) {
text += '\n';
- text += Drupal.t('Press the down arrow key to create a new button group in a new row.');
- }
- // If this position is the last one in this row then tell the user that
- // moving the button to the next group will create a new group.
- if (groupPosition === groupPositionCount && position === positionCount) {
- text += '\n';
- text += Drupal.t('This is the last group. Move the button forward to create a new group.');
+ text += Drupal.t('Press the down arrow key to create a new row.');
}
Drupal.announce(text, 'assertive');
- }
- },
+ },
- /**
- * Provides help information when a button is clicked.
- *
- * @param {jQuery.Event} event
- * The click event for the button click.
- */
- announceButtonHelp(event) {
- const $link = $(event.currentTarget);
- const $button = $link.parent();
- const enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
- let message;
+ /**
+ * Announces current button position.
+ *
+ * @param {jQuery} $button
+ * A jQuery set that contains an li element that wraps a button.
+ */
+ announceButtonPosition($button) {
+ const $row = $button.closest('.ckeditor-row');
+ const $rows = $row.parent().children();
+ const $buttons = $button.closest('.ckeditor-buttons').children();
+ const $group = $button.closest('.ckeditor-toolbar-group');
+ const $groups = $group.parent().children();
+ const groupPosition = $groups.index($group) + 1;
+ const groupPositionCount = $groups.not('.placeholder').length;
+ const position = $buttons.index($button) + 1;
+ const positionCount = $buttons.length;
+ const row = $rows.index($row) + 1;
+ const rowCount = $rows.not('.placeholder').length;
+ // The name of the button separator is 'button separator' and its type
+ // is 'separator', so we do not want to print the type of this item,
+ // otherwise the UA will speak 'button separator separator'.
+ const type =
+ $button.attr('data-drupal-ckeditor-type') === 'separator'
+ ? ''
+ : Drupal.t('button');
+ let text;
+ // The button is located in the available button set.
+ if ($button.closest('.ckeditor-toolbar-disabled').length > 0) {
+ text = Drupal.t('@name @type.', {
+ '@name': $button.children().attr('aria-label'),
+ '@type': type,
+ });
+ text += `\n${Drupal.t('Press the down arrow key to activate.')}`;
- if (enabled) {
- message = Drupal.t('The "@name" button is currently enabled.', {
- '@name': $link.attr('aria-label'),
- });
- message += `\n${Drupal.t('Use the keyboard arrow keys to change the position of this button.')}`;
- message += `\n${Drupal.t('Press the up arrow key on the top row to disable the button.')}`;
- }
- else {
- message = Drupal.t('The "@name" button is currently disabled.', {
- '@name': $link.attr('aria-label'),
- });
- message += `\n${Drupal.t('Use the down arrow key to move this button into the active toolbar.')}`;
- }
- Drupal.announce(message);
- event.preventDefault();
- },
+ Drupal.announce(text, 'assertive');
+ }
+ // The button is in the active toolbar.
+ else if ($group.not('.placeholder').length === 1) {
+ text = Drupal.t(
+ '@name @type in position @position of @positionCount in @groupName button group in row @row of @rowCount.',
+ {
+ '@name': $button.children().attr('aria-label'),
+ '@type': type,
+ '@position': position,
+ '@positionCount': positionCount,
+ '@groupName': $group.attr(
+ 'data-drupal-ckeditor-toolbar-group-name',
+ ),
+ '@row': row,
+ '@rowCount': rowCount,
+ },
+ );
+ // If this position is the first in the last row then tell the user that
+ // pressing the down arrow key will create a new row.
+ if (groupPosition === 1 && position === 1 && row === rowCount) {
+ text += '\n';
+ text += Drupal.t(
+ 'Press the down arrow key to create a new button group in a new row.',
+ );
+ }
+ // If this position is the last one in this row then tell the user that
+ // moving the button to the next group will create a new group.
+ if (
+ groupPosition === groupPositionCount &&
+ position === positionCount
+ ) {
+ text += '\n';
+ text += Drupal.t(
+ 'This is the last group. Move the button forward to create a new group.',
+ );
+ }
+ Drupal.announce(text, 'assertive');
+ }
+ },
+
+ /**
+ * Provides help information when a button is clicked.
+ *
+ * @param {jQuery.Event} event
+ * The click event for the button click.
+ */
+ announceButtonHelp(event) {
+ const $link = $(event.currentTarget);
+ const $button = $link.parent();
+ const enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
+ let message;
- /**
- * Provides help information when a separator is clicked.
- *
- * @param {jQuery.Event} event
- * The click event for the separator click.
- */
- announceSeparatorHelp(event) {
- const $link = $(event.currentTarget);
- const $button = $link.parent();
- const enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
- let message;
+ if (enabled) {
+ message = Drupal.t('The "@name" button is currently enabled.', {
+ '@name': $link.attr('aria-label'),
+ });
+ message += `\n${Drupal.t(
+ 'Use the keyboard arrow keys to change the position of this button.',
+ )}`;
+ message += `\n${Drupal.t(
+ 'Press the up arrow key on the top row to disable the button.',
+ )}`;
+ } else {
+ message = Drupal.t('The "@name" button is currently disabled.', {
+ '@name': $link.attr('aria-label'),
+ });
+ message += `\n${Drupal.t(
+ 'Use the down arrow key to move this button into the active toolbar.',
+ )}`;
+ }
+ Drupal.announce(message);
+ event.preventDefault();
+ },
- if (enabled) {
- message = Drupal.t('This @name is currently enabled.', {
- '@name': $link.attr('aria-label'),
- });
- message += `\n${Drupal.t('Use the keyboard arrow keys to change the position of this separator.')}`;
- }
- else {
- message = Drupal.t('Separators are used to visually split individual buttons.');
- message += `\n${Drupal.t('This @name is currently disabled.', {
- '@name': $link.attr('aria-label'),
- })}`;
- message += `\n${Drupal.t('Use the down arrow key to move this separator into the active toolbar.')}`;
- message += `\n${Drupal.t('You may add multiple separators to each button group.')}`;
- }
- Drupal.announce(message);
- event.preventDefault();
+ /**
+ * Provides help information when a separator is clicked.
+ *
+ * @param {jQuery.Event} event
+ * The click event for the separator click.
+ */
+ announceSeparatorHelp(event) {
+ const $link = $(event.currentTarget);
+ const $button = $link.parent();
+ const enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
+ let message;
+
+ if (enabled) {
+ message = Drupal.t('This @name is currently enabled.', {
+ '@name': $link.attr('aria-label'),
+ });
+ message += `\n${Drupal.t(
+ 'Use the keyboard arrow keys to change the position of this separator.',
+ )}`;
+ } else {
+ message = Drupal.t(
+ 'Separators are used to visually split individual buttons.',
+ );
+ message += `\n${Drupal.t('This @name is currently disabled.', {
+ '@name': $link.attr('aria-label'),
+ })}`;
+ message += `\n${Drupal.t(
+ 'Use the down arrow key to move this separator into the active toolbar.',
+ )}`;
+ message += `\n${Drupal.t(
+ 'You may add multiple separators to each button group.',
+ )}`;
+ }
+ Drupal.announce(message);
+ event.preventDefault();
+ },
},
- });
-}(Drupal, Backbone, jQuery));
+ );
+})(Drupal, Backbone, jQuery);
diff --git a/core/modules/ckeditor/js/views/ControllerView.es6.js b/core/modules/ckeditor/js/views/ControllerView.es6.js
index 8eaeec0..1e11f97 100644
--- a/core/modules/ckeditor/js/views/ControllerView.es6.js
+++ b/core/modules/ckeditor/js/views/ControllerView.es6.js
@@ -3,369 +3,418 @@
* A Backbone View acting as a controller for CKEditor toolbar configuration.
*/
-(function ($, Drupal, Backbone, CKEDITOR, _) {
- Drupal.ckeditor.ControllerView = Backbone.View.extend(/** @lends Drupal.ckeditor.ControllerView# */{
+(function($, Drupal, Backbone, CKEDITOR, _) {
+ Drupal.ckeditor.ControllerView = Backbone.View.extend(
+ /** @lends Drupal.ckeditor.ControllerView# */ {
+ /**
+ * @type {object}
+ */
+ events: {},
- /**
- * @type {object}
- */
- events: {},
+ /**
+ * Backbone View acting as a controller for CKEditor toolbar configuration.
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ this.getCKEditorFeatures(
+ this.model.get('hiddenEditorConfig'),
+ this.disableFeaturesDisallowedByFilters.bind(this),
+ );
- /**
- * Backbone View acting as a controller for CKEditor toolbar configuration.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- this.getCKEditorFeatures(this.model.get('hiddenEditorConfig'), this.disableFeaturesDisallowedByFilters.bind(this));
+ // Push the active editor configuration to the textarea.
+ this.model.listenTo(
+ this.model,
+ 'change:activeEditorConfig',
+ this.model.sync,
+ );
+ this.listenTo(this.model, 'change:isDirty', this.parseEditorDOM);
+ },
- // Push the active editor configuration to the textarea.
- this.model.listenTo(this.model, 'change:activeEditorConfig', this.model.sync);
- this.listenTo(this.model, 'change:isDirty', this.parseEditorDOM);
- },
-
- /**
- * Converts the active toolbar DOM structure to an object representation.
- *
- * @param {Drupal.ckeditor.ConfigurationModel} model
- * The state model for the CKEditor configuration.
- * @param {bool} isDirty
- * Tracks whether the active toolbar DOM structure has been changed.
- * isDirty is toggled back to false in this method.
- * @param {object} options
- * An object that includes:
- * @param {bool} [options.broadcast]
- * A flag that controls whether a CKEditorToolbarChanged event should be
- * fired for configuration changes.
- *
- * @fires event:CKEditorToolbarChanged
- */
- parseEditorDOM(model, isDirty, options) {
- if (isDirty) {
- const currentConfig = this.model.get('activeEditorConfig');
+ /**
+ * Converts the active toolbar DOM structure to an object representation.
+ *
+ * @param {Drupal.ckeditor.ConfigurationModel} model
+ * The state model for the CKEditor configuration.
+ * @param {bool} isDirty
+ * Tracks whether the active toolbar DOM structure has been changed.
+ * isDirty is toggled back to false in this method.
+ * @param {object} options
+ * An object that includes:
+ * @param {bool} [options.broadcast]
+ * A flag that controls whether a CKEditorToolbarChanged event should be
+ * fired for configuration changes.
+ *
+ * @fires event:CKEditorToolbarChanged
+ */
+ parseEditorDOM(model, isDirty, options) {
+ if (isDirty) {
+ const currentConfig = this.model.get('activeEditorConfig');
- // Process the rows.
- const rows = [];
- this.$el
- .find('.ckeditor-active-toolbar-configuration')
- .children('.ckeditor-row').each(function () {
- const groups = [];
- // Process the button groups.
- $(this).find('.ckeditor-toolbar-group').each(function () {
- const $group = $(this);
- const $buttons = $group.find('.ckeditor-button');
- if ($buttons.length) {
- const group = {
- name: $group.attr('data-drupal-ckeditor-toolbar-group-name'),
- items: [],
- };
- $group.find('.ckeditor-button, .ckeditor-multiple-button').each(function () {
- group.items.push($(this).attr('data-drupal-ckeditor-button-name'));
+ // Process the rows.
+ const rows = [];
+ this.$el
+ .find('.ckeditor-active-toolbar-configuration')
+ .children('.ckeditor-row')
+ .each(function() {
+ const groups = [];
+ // Process the button groups.
+ $(this)
+ .find('.ckeditor-toolbar-group')
+ .each(function() {
+ const $group = $(this);
+ const $buttons = $group.find('.ckeditor-button');
+ if ($buttons.length) {
+ const group = {
+ name: $group.attr(
+ 'data-drupal-ckeditor-toolbar-group-name',
+ ),
+ items: [],
+ };
+ $group
+ .find('.ckeditor-button, .ckeditor-multiple-button')
+ .each(function() {
+ group.items.push(
+ $(this).attr('data-drupal-ckeditor-button-name'),
+ );
+ });
+ groups.push(group);
+ }
});
- groups.push(group);
+ if (groups.length) {
+ rows.push(groups);
}
});
- if (groups.length) {
- rows.push(groups);
- }
- });
- this.model.set('activeEditorConfig', rows);
- // Mark the model as clean. Whether or not the sync to the textfield
- // occurs depends on the activeEditorConfig attribute firing a change
- // event. The DOM has at least been processed and posted, so as far as
- // the model is concerned, it is clean.
- this.model.set('isDirty', false);
+ this.model.set('activeEditorConfig', rows);
+ // Mark the model as clean. Whether or not the sync to the textfield
+ // occurs depends on the activeEditorConfig attribute firing a change
+ // event. The DOM has at least been processed and posted, so as far as
+ // the model is concerned, it is clean.
+ this.model.set('isDirty', false);
- // Determine whether we should trigger an event.
- if (options.broadcast !== false) {
- const prev = this.getButtonList(currentConfig);
- const next = this.getButtonList(rows);
- if (prev.length !== next.length) {
- this.$el
- .find('.ckeditor-toolbar-active')
- .trigger('CKEditorToolbarChanged', [
- (prev.length < next.length) ? 'added' : 'removed',
- _.difference(_.union(prev, next), _.intersection(prev, next))[0],
- ]);
+ // Determine whether we should trigger an event.
+ if (options.broadcast !== false) {
+ const prev = this.getButtonList(currentConfig);
+ const next = this.getButtonList(rows);
+ if (prev.length !== next.length) {
+ this.$el
+ .find('.ckeditor-toolbar-active')
+ .trigger('CKEditorToolbarChanged', [
+ prev.length < next.length ? 'added' : 'removed',
+ _.difference(
+ _.union(prev, next),
+ _.intersection(prev, next),
+ )[0],
+ ]);
+ }
}
}
- }
- },
-
- /**
- * Asynchronously retrieve the metadata for all available CKEditor features.
- *
- * In order to get a list of all features needed by CKEditor, we create a
- * hidden CKEditor instance, then check the CKEditor's "allowedContent"
- * filter settings. Because creating an instance is expensive, a callback
- * must be provided that will receive a hash of {@link Drupal.EditorFeature}
- * features keyed by feature (button) name.
- *
- * @param {object} CKEditorConfig
- * An object that represents the configuration settings for a CKEditor
- * editor component.
- * @param {function} callback
- * A function to invoke when the instanceReady event is fired by the
- * CKEditor object.
- */
- getCKEditorFeatures(CKEditorConfig, callback) {
- const getProperties = function (CKEPropertiesList) {
- return (_.isObject(CKEPropertiesList)) ? _.keys(CKEPropertiesList) : [];
- };
+ },
- const convertCKERulesToEditorFeature = function (feature, CKEFeatureRules) {
- for (let i = 0; i < CKEFeatureRules.length; i++) {
- const CKERule = CKEFeatureRules[i];
- const rule = new Drupal.EditorFeatureHTMLRule();
+ /**
+ * Asynchronously retrieve the metadata for all available CKEditor features.
+ *
+ * In order to get a list of all features needed by CKEditor, we create a
+ * hidden CKEditor instance, then check the CKEditor's "allowedContent"
+ * filter settings. Because creating an instance is expensive, a callback
+ * must be provided that will receive a hash of {@link Drupal.EditorFeature}
+ * features keyed by feature (button) name.
+ *
+ * @param {object} CKEditorConfig
+ * An object that represents the configuration settings for a CKEditor
+ * editor component.
+ * @param {function} callback
+ * A function to invoke when the instanceReady event is fired by the
+ * CKEditor object.
+ */
+ getCKEditorFeatures(CKEditorConfig, callback) {
+ const getProperties = function(CKEPropertiesList) {
+ return _.isObject(CKEPropertiesList) ? _.keys(CKEPropertiesList) : [];
+ };
- // Tags.
- const tags = getProperties(CKERule.elements);
- rule.required.tags = (CKERule.propertiesOnly) ? [] : tags;
- rule.allowed.tags = tags;
- // Attributes.
- rule.required.attributes = getProperties(CKERule.requiredAttributes);
- rule.allowed.attributes = getProperties(CKERule.attributes);
- // Styles.
- rule.required.styles = getProperties(CKERule.requiredStyles);
- rule.allowed.styles = getProperties(CKERule.styles);
- // Classes.
- rule.required.classes = getProperties(CKERule.requiredClasses);
- rule.allowed.classes = getProperties(CKERule.classes);
- // Raw.
- rule.raw = CKERule;
-
- feature.addHTMLRule(rule);
- }
- };
+ const convertCKERulesToEditorFeature = function(
+ feature,
+ CKEFeatureRules,
+ ) {
+ for (let i = 0; i < CKEFeatureRules.length; i++) {
+ const CKERule = CKEFeatureRules[i];
+ const rule = new Drupal.EditorFeatureHTMLRule();
- // Create hidden CKEditor with all features enabled, retrieve metadata.
- // @see \Drupal\ckeditor\Plugin\Editor\CKEditor::buildConfigurationForm().
- const hiddenCKEditorID = 'ckeditor-hidden';
- if (CKEDITOR.instances[hiddenCKEditorID]) {
- CKEDITOR.instances[hiddenCKEditorID].destroy(true);
- }
- // Load external plugins, if any.
- const hiddenEditorConfig = this.model.get('hiddenEditorConfig');
- if (hiddenEditorConfig.drupalExternalPlugins) {
- const externalPlugins = hiddenEditorConfig.drupalExternalPlugins;
- Object.keys(externalPlugins || {}).forEach((pluginName) => {
- CKEDITOR.plugins.addExternal(pluginName, externalPlugins[pluginName], '');
- });
- }
- CKEDITOR.inline($(`#${hiddenCKEditorID}`).get(0), CKEditorConfig);
+ // Tags.
+ const tags = getProperties(CKERule.elements);
+ rule.required.tags = CKERule.propertiesOnly ? [] : tags;
+ rule.allowed.tags = tags;
+ // Attributes.
+ rule.required.attributes = getProperties(
+ CKERule.requiredAttributes,
+ );
+ rule.allowed.attributes = getProperties(CKERule.attributes);
+ // Styles.
+ rule.required.styles = getProperties(CKERule.requiredStyles);
+ rule.allowed.styles = getProperties(CKERule.styles);
+ // Classes.
+ rule.required.classes = getProperties(CKERule.requiredClasses);
+ rule.allowed.classes = getProperties(CKERule.classes);
+ // Raw.
+ rule.raw = CKERule;
- // Once the instance is ready, retrieve the allowedContent filter rules
- // and convert them to Drupal.EditorFeature objects.
- CKEDITOR.once('instanceReady', (e) => {
- if (e.editor.name === hiddenCKEditorID) {
- // First collect all CKEditor allowedContent rules.
- const CKEFeatureRulesMap = {};
- const rules = e.editor.filter.allowedContent;
- let rule;
- let name;
- for (let i = 0; i < rules.length; i++) {
- rule = rules[i];
- name = rule.featureName || ':(';
- if (!CKEFeatureRulesMap[name]) {
- CKEFeatureRulesMap[name] = [];
- }
- CKEFeatureRulesMap[name].push(rule);
+ feature.addHTMLRule(rule);
}
+ };
- // Now convert these to Drupal.EditorFeature objects. And track which
- // buttons are mapped to which features.
- // @see getFeatureForButton()
- const features = {};
- const buttonsToFeatures = {};
- Object.keys(CKEFeatureRulesMap).forEach((featureName) => {
- const feature = new Drupal.EditorFeature(featureName);
- convertCKERulesToEditorFeature(feature, CKEFeatureRulesMap[featureName]);
- features[featureName] = feature;
- const command = e.editor.getCommand(featureName);
- if (command) {
- buttonsToFeatures[command.uiItems[0].name] = featureName;
- }
+ // Create hidden CKEditor with all features enabled, retrieve metadata.
+ // @see \Drupal\ckeditor\Plugin\Editor\CKEditor::buildConfigurationForm().
+ const hiddenCKEditorID = 'ckeditor-hidden';
+ if (CKEDITOR.instances[hiddenCKEditorID]) {
+ CKEDITOR.instances[hiddenCKEditorID].destroy(true);
+ }
+ // Load external plugins, if any.
+ const hiddenEditorConfig = this.model.get('hiddenEditorConfig');
+ if (hiddenEditorConfig.drupalExternalPlugins) {
+ const externalPlugins = hiddenEditorConfig.drupalExternalPlugins;
+ Object.keys(externalPlugins || {}).forEach(pluginName => {
+ CKEDITOR.plugins.addExternal(
+ pluginName,
+ externalPlugins[pluginName],
+ '',
+ );
});
-
- callback(features, buttonsToFeatures);
}
- });
- },
+ CKEDITOR.inline($(`#${hiddenCKEditorID}`).get(0), CKEditorConfig);
- /**
- * Retrieves the feature for a given button from featuresMetadata. Returns
- * false if the given button is in fact a divider.
- *
- * @param {string} button
- * The name of a CKEditor button.
- *
- * @return {object}
- * The feature metadata object for a button.
- */
- getFeatureForButton(button) {
- // Return false if the button being added is a divider.
- if (button === '-') {
- return false;
- }
-
- // Get a Drupal.editorFeature object that contains all metadata for
- // the feature that was just added or removed. Not every feature has
- // such metadata.
- let featureName = this.model.get('buttonsToFeatures')[button.toLowerCase()];
- // Features without an associated command do not have a 'feature name' by
- // default, so we use the lowercased button name instead.
- if (!featureName) {
- featureName = button.toLowerCase();
- }
- const featuresMetadata = this.model.get('featuresMetadata');
- if (!featuresMetadata[featureName]) {
- featuresMetadata[featureName] = new Drupal.EditorFeature(featureName);
- this.model.set('featuresMetadata', featuresMetadata);
- }
- return featuresMetadata[featureName];
- },
+ // Once the instance is ready, retrieve the allowedContent filter rules
+ // and convert them to Drupal.EditorFeature objects.
+ CKEDITOR.once('instanceReady', e => {
+ if (e.editor.name === hiddenCKEditorID) {
+ // First collect all CKEditor allowedContent rules.
+ const CKEFeatureRulesMap = {};
+ const rules = e.editor.filter.allowedContent;
+ let rule;
+ let name;
+ for (let i = 0; i < rules.length; i++) {
+ rule = rules[i];
+ name = rule.featureName || ':(';
+ if (!CKEFeatureRulesMap[name]) {
+ CKEFeatureRulesMap[name] = [];
+ }
+ CKEFeatureRulesMap[name].push(rule);
+ }
- /**
- * Checks buttons against filter settings; disables disallowed buttons.
- *
- * @param {object} features
- * A map of {@link Drupal.EditorFeature} objects.
- * @param {object} buttonsToFeatures
- * Object containing the button-to-feature mapping.
- *
- * @see Drupal.ckeditor.ControllerView#getFeatureForButton
- */
- disableFeaturesDisallowedByFilters(features, buttonsToFeatures) {
- this.model.set('featuresMetadata', features);
- // Store the button-to-feature mapping. Needs to happen only once, because
- // the same buttons continue to have the same features; only the rules for
- // specific features may change.
- // @see getFeatureForButton()
- this.model.set('buttonsToFeatures', buttonsToFeatures);
+ // Now convert these to Drupal.EditorFeature objects. And track which
+ // buttons are mapped to which features.
+ // @see getFeatureForButton()
+ const features = {};
+ const buttonsToFeatures = {};
+ Object.keys(CKEFeatureRulesMap).forEach(featureName => {
+ const feature = new Drupal.EditorFeature(featureName);
+ convertCKERulesToEditorFeature(
+ feature,
+ CKEFeatureRulesMap[featureName],
+ );
+ features[featureName] = feature;
+ const command = e.editor.getCommand(featureName);
+ if (command) {
+ buttonsToFeatures[command.uiItems[0].name] = featureName;
+ }
+ });
- // Ensure that toolbar configuration changes are broadcast.
- this.broadcastConfigurationChanges(this.$el);
+ callback(features, buttonsToFeatures);
+ }
+ });
+ },
- // Initialization: not all of the default toolbar buttons may be allowed
- // by the current filter settings. Remove any of the default toolbar
- // buttons that require more permissive filter settings. The remaining
- // default toolbar buttons are marked as "added".
- let existingButtons = [];
- // Loop through each button group after flattening the groups from the
- // toolbar row arrays.
- const buttonGroups = _.flatten(this.model.get('activeEditorConfig'));
- for (let i = 0; i < buttonGroups.length; i++) {
- // Pull the button names from each toolbar button group.
- const buttons = buttonGroups[i].items;
- for (let k = 0; k < buttons.length; k++) {
- existingButtons.push(buttons[k]);
- }
- }
- // Remove duplicate buttons.
- existingButtons = _.unique(existingButtons);
- // Prepare the active toolbar and available-button toolbars.
- for (let n = 0; n < existingButtons.length; n++) {
- const button = existingButtons[n];
- const feature = this.getFeatureForButton(button);
- // Skip dividers.
- if (feature === false) {
- continue;
+ /**
+ * Retrieves the feature for a given button from featuresMetadata. Returns
+ * false if the given button is in fact a divider.
+ *
+ * @param {string} button
+ * The name of a CKEditor button.
+ *
+ * @return {object}
+ * The feature metadata object for a button.
+ */
+ getFeatureForButton(button) {
+ // Return false if the button being added is a divider.
+ if (button === '-') {
+ return false;
}
- if (Drupal.editorConfiguration.featureIsAllowedByFilters(feature)) {
- // Existing toolbar buttons are in fact "added features".
- this.$el.find('.ckeditor-toolbar-active').trigger('CKEditorToolbarChanged', ['added', existingButtons[n]]);
+ // Get a Drupal.editorFeature object that contains all metadata for
+ // the feature that was just added or removed. Not every feature has
+ // such metadata.
+ let featureName = this.model.get('buttonsToFeatures')[
+ button.toLowerCase()
+ ];
+ // Features without an associated command do not have a 'feature name' by
+ // default, so we use the lowercased button name instead.
+ if (!featureName) {
+ featureName = button.toLowerCase();
}
- else {
- // Move the button element from the active the active toolbar to the
- // list of available buttons.
- $(`.ckeditor-toolbar-active li[data-drupal-ckeditor-button-name="${button}"]`)
- .detach()
- .appendTo('.ckeditor-toolbar-disabled > .ckeditor-toolbar-available > ul');
- // Update the toolbar value field.
- this.model.set({ isDirty: true }, { broadcast: false });
+ const featuresMetadata = this.model.get('featuresMetadata');
+ if (!featuresMetadata[featureName]) {
+ featuresMetadata[featureName] = new Drupal.EditorFeature(featureName);
+ this.model.set('featuresMetadata', featuresMetadata);
}
- }
- },
+ return featuresMetadata[featureName];
+ },
+
+ /**
+ * Checks buttons against filter settings; disables disallowed buttons.
+ *
+ * @param {object} features
+ * A map of {@link Drupal.EditorFeature} objects.
+ * @param {object} buttonsToFeatures
+ * Object containing the button-to-feature mapping.
+ *
+ * @see Drupal.ckeditor.ControllerView#getFeatureForButton
+ */
+ disableFeaturesDisallowedByFilters(features, buttonsToFeatures) {
+ this.model.set('featuresMetadata', features);
+ // Store the button-to-feature mapping. Needs to happen only once, because
+ // the same buttons continue to have the same features; only the rules for
+ // specific features may change.
+ // @see getFeatureForButton()
+ this.model.set('buttonsToFeatures', buttonsToFeatures);
- /**
- * Sets up broadcasting of CKEditor toolbar configuration changes.
- *
- * @param {jQuery} $ckeditorToolbar
- * The active toolbar DOM element wrapped in jQuery.
- */
- broadcastConfigurationChanges($ckeditorToolbar) {
- const view = this;
- const hiddenEditorConfig = this.model.get('hiddenEditorConfig');
- const getFeatureForButton = this.getFeatureForButton.bind(this);
- const getCKEditorFeatures = this.getCKEditorFeatures.bind(this);
- $ckeditorToolbar
- .find('.ckeditor-toolbar-active')
- // Listen for CKEditor toolbar configuration changes. When a button is
- // added/removed, call an appropriate Drupal.editorConfiguration method.
- .on('CKEditorToolbarChanged.ckeditorAdmin', (event, action, button) => {
- const feature = getFeatureForButton(button);
+ // Ensure that toolbar configuration changes are broadcast.
+ this.broadcastConfigurationChanges(this.$el);
- // Early-return if the button being added is a divider.
+ // Initialization: not all of the default toolbar buttons may be allowed
+ // by the current filter settings. Remove any of the default toolbar
+ // buttons that require more permissive filter settings. The remaining
+ // default toolbar buttons are marked as "added".
+ let existingButtons = [];
+ // Loop through each button group after flattening the groups from the
+ // toolbar row arrays.
+ const buttonGroups = _.flatten(this.model.get('activeEditorConfig'));
+ for (let i = 0; i < buttonGroups.length; i++) {
+ // Pull the button names from each toolbar button group.
+ const buttons = buttonGroups[i].items;
+ for (let k = 0; k < buttons.length; k++) {
+ existingButtons.push(buttons[k]);
+ }
+ }
+ // Remove duplicate buttons.
+ existingButtons = _.unique(existingButtons);
+ // Prepare the active toolbar and available-button toolbars.
+ for (let n = 0; n < existingButtons.length; n++) {
+ const button = existingButtons[n];
+ const feature = this.getFeatureForButton(button);
+ // Skip dividers.
if (feature === false) {
- return;
+ continue;
}
- // Trigger a standardized text editor configuration event to indicate
- // whether a feature was added or removed, so that filters can react.
- const configEvent = (action === 'added') ? 'addedFeature' : 'removedFeature';
- Drupal.editorConfiguration[configEvent](feature);
- })
- // Listen for CKEditor plugin settings changes. When a plugin setting is
- // changed, rebuild the CKEditor features metadata.
- .on('CKEditorPluginSettingsChanged.ckeditorAdmin', (event, settingsChanges) => {
- // Update hidden CKEditor configuration.
- Object.keys(settingsChanges || {}).forEach((key) => {
- hiddenEditorConfig[key] = settingsChanges[key];
- });
+ if (Drupal.editorConfiguration.featureIsAllowedByFilters(feature)) {
+ // Existing toolbar buttons are in fact "added features".
+ this.$el
+ .find('.ckeditor-toolbar-active')
+ .trigger('CKEditorToolbarChanged', ['added', existingButtons[n]]);
+ } else {
+ // Move the button element from the active the active toolbar to the
+ // list of available buttons.
+ $(
+ `.ckeditor-toolbar-active li[data-drupal-ckeditor-button-name="${button}"]`,
+ )
+ .detach()
+ .appendTo(
+ '.ckeditor-toolbar-disabled > .ckeditor-toolbar-available > ul',
+ );
+ // Update the toolbar value field.
+ this.model.set({ isDirty: true }, { broadcast: false });
+ }
+ }
+ },
+
+ /**
+ * Sets up broadcasting of CKEditor toolbar configuration changes.
+ *
+ * @param {jQuery} $ckeditorToolbar
+ * The active toolbar DOM element wrapped in jQuery.
+ */
+ broadcastConfigurationChanges($ckeditorToolbar) {
+ const view = this;
+ const hiddenEditorConfig = this.model.get('hiddenEditorConfig');
+ const getFeatureForButton = this.getFeatureForButton.bind(this);
+ const getCKEditorFeatures = this.getCKEditorFeatures.bind(this);
+ $ckeditorToolbar
+ .find('.ckeditor-toolbar-active')
+ // Listen for CKEditor toolbar configuration changes. When a button is
+ // added/removed, call an appropriate Drupal.editorConfiguration method.
+ .on(
+ 'CKEditorToolbarChanged.ckeditorAdmin',
+ (event, action, button) => {
+ const feature = getFeatureForButton(button);
- // Retrieve features for the updated hidden CKEditor configuration.
- getCKEditorFeatures(hiddenEditorConfig, (features) => {
- // Trigger a standardized text editor configuration event for each
- // feature that was modified by the configuration changes.
- const featuresMetadata = view.model.get('featuresMetadata');
- Object.keys(features || {}).forEach((name) => {
- const feature = features[name];
- if (featuresMetadata.hasOwnProperty(name) && !_.isEqual(featuresMetadata[name], feature)) {
- Drupal.editorConfiguration.modifiedFeature(feature);
+ // Early-return if the button being added is a divider.
+ if (feature === false) {
+ return;
}
- });
- // Update the CKEditor features metadata.
- view.model.set('featuresMetadata', features);
- });
- });
- },
- /**
- * Returns the list of buttons from an editor configuration.
- *
- * @param {object} config
- * A CKEditor configuration object.
- *
- * @return {Array}
- * A list of buttons in the CKEditor configuration.
- */
- getButtonList(config) {
- const buttons = [];
- // Remove the rows.
- config = _.flatten(config);
+ // Trigger a standardized text editor configuration event to indicate
+ // whether a feature was added or removed, so that filters can react.
+ const configEvent =
+ action === 'added' ? 'addedFeature' : 'removedFeature';
+ Drupal.editorConfiguration[configEvent](feature);
+ },
+ )
+ // Listen for CKEditor plugin settings changes. When a plugin setting is
+ // changed, rebuild the CKEditor features metadata.
+ .on(
+ 'CKEditorPluginSettingsChanged.ckeditorAdmin',
+ (event, settingsChanges) => {
+ // Update hidden CKEditor configuration.
+ Object.keys(settingsChanges || {}).forEach(key => {
+ hiddenEditorConfig[key] = settingsChanges[key];
+ });
+
+ // Retrieve features for the updated hidden CKEditor configuration.
+ getCKEditorFeatures(hiddenEditorConfig, features => {
+ // Trigger a standardized text editor configuration event for each
+ // feature that was modified by the configuration changes.
+ const featuresMetadata = view.model.get('featuresMetadata');
+ Object.keys(features || {}).forEach(name => {
+ const feature = features[name];
+ if (
+ featuresMetadata.hasOwnProperty(name) &&
+ !_.isEqual(featuresMetadata[name], feature)
+ ) {
+ Drupal.editorConfiguration.modifiedFeature(feature);
+ }
+ });
+ // Update the CKEditor features metadata.
+ view.model.set('featuresMetadata', features);
+ });
+ },
+ );
+ },
- // Loop through the button groups and pull out the buttons.
- config.forEach((group) => {
- group.items.forEach((button) => {
- buttons.push(button);
+ /**
+ * Returns the list of buttons from an editor configuration.
+ *
+ * @param {object} config
+ * A CKEditor configuration object.
+ *
+ * @return {Array}
+ * A list of buttons in the CKEditor configuration.
+ */
+ getButtonList(config) {
+ const buttons = [];
+ // Remove the rows.
+ config = _.flatten(config);
+
+ // Loop through the button groups and pull out the buttons.
+ config.forEach(group => {
+ group.items.forEach(button => {
+ buttons.push(button);
+ });
});
- });
- // Remove the dividing elements if any.
- return _.without(buttons, '-');
+ // Remove the dividing elements if any.
+ return _.without(buttons, '-');
+ },
},
- });
-}(jQuery, Drupal, Backbone, CKEDITOR, _));
+ );
+})(jQuery, Drupal, Backbone, CKEDITOR, _);
diff --git a/core/modules/ckeditor/js/views/KeyboardView.es6.js b/core/modules/ckeditor/js/views/KeyboardView.es6.js
index cf2ead9..2502833 100644
--- a/core/modules/ckeditor/js/views/KeyboardView.es6.js
+++ b/core/modules/ckeditor/js/views/KeyboardView.es6.js
@@ -3,281 +3,310 @@
* Backbone View providing the aural view of CKEditor keyboard UX configuration.
*/
-(function ($, Drupal, Backbone, _) {
- Drupal.ckeditor.KeyboardView = Backbone.View.extend(/** @lends Drupal.ckeditor.KeyboardView# */{
+(function($, Drupal, Backbone, _) {
+ Drupal.ckeditor.KeyboardView = Backbone.View.extend(
+ /** @lends Drupal.ckeditor.KeyboardView# */ {
+ /**
+ * Backbone View for CKEditor toolbar configuration; keyboard UX.
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ // Add keyboard arrow support.
+ this.$el.on(
+ 'keydown.ckeditor',
+ '.ckeditor-buttons a, .ckeditor-multiple-buttons a',
+ this.onPressButton.bind(this),
+ );
+ this.$el.on(
+ 'keydown.ckeditor',
+ '[data-drupal-ckeditor-type="group"]',
+ this.onPressGroup.bind(this),
+ );
+ },
- /**
- * Backbone View for CKEditor toolbar configuration; keyboard UX.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- // Add keyboard arrow support.
- this.$el.on('keydown.ckeditor', '.ckeditor-buttons a, .ckeditor-multiple-buttons a', this.onPressButton.bind(this));
- this.$el.on('keydown.ckeditor', '[data-drupal-ckeditor-type="group"]', this.onPressGroup.bind(this));
- },
-
- /**
- * @inheritdoc
- */
- render() {
- },
+ /**
+ * @inheritdoc
+ */
+ render() {},
- /**
- * Handles keypresses on a CKEditor configuration button.
- *
- * @param {jQuery.Event} event
- * The keypress event triggered.
- */
- onPressButton(event) {
- const upDownKeys = [
- 38, // Up arrow.
- 63232, // Safari up arrow.
- 40, // Down arrow.
- 63233, // Safari down arrow.
- ];
- const leftRightKeys = [
- 37, // Left arrow.
- 63234, // Safari left arrow.
- 39, // Right arrow.
- 63235, // Safari right arrow.
- ];
+ /**
+ * Handles keypresses on a CKEditor configuration button.
+ *
+ * @param {jQuery.Event} event
+ * The keypress event triggered.
+ */
+ onPressButton(event) {
+ const upDownKeys = [
+ 38, // Up arrow.
+ 63232, // Safari up arrow.
+ 40, // Down arrow.
+ 63233, // Safari down arrow.
+ ];
+ const leftRightKeys = [
+ 37, // Left arrow.
+ 63234, // Safari left arrow.
+ 39, // Right arrow.
+ 63235, // Safari right arrow.
+ ];
- // Respond to an enter key press. Prevent the bubbling of the enter key
- // press to the button group parent element.
- if (event.keyCode === 13) {
- event.stopPropagation();
- }
+ // Respond to an enter key press. Prevent the bubbling of the enter key
+ // press to the button group parent element.
+ if (event.keyCode === 13) {
+ event.stopPropagation();
+ }
- // Only take action when a direction key is pressed.
- if (_.indexOf(_.union(upDownKeys, leftRightKeys), event.keyCode) > -1) {
- let view = this;
- let $target = $(event.currentTarget);
- let $button = $target.parent();
- const $container = $button.parent();
- let $group = $button.closest('.ckeditor-toolbar-group');
- let $row;
- const containerType = $container.data('drupal-ckeditor-button-sorting');
- const $availableButtons = this.$el.find('[data-drupal-ckeditor-button-sorting="source"]');
- const $activeButtons = this.$el.find('.ckeditor-toolbar-active');
- // The current location of the button, just in case it needs to be put
- // back.
- const $originalGroup = $group;
- let dir;
+ // Only take action when a direction key is pressed.
+ if (_.indexOf(_.union(upDownKeys, leftRightKeys), event.keyCode) > -1) {
+ let view = this;
+ let $target = $(event.currentTarget);
+ let $button = $target.parent();
+ const $container = $button.parent();
+ let $group = $button.closest('.ckeditor-toolbar-group');
+ let $row;
+ const containerType = $container.data(
+ 'drupal-ckeditor-button-sorting',
+ );
+ const $availableButtons = this.$el.find(
+ '[data-drupal-ckeditor-button-sorting="source"]',
+ );
+ const $activeButtons = this.$el.find('.ckeditor-toolbar-active');
+ // The current location of the button, just in case it needs to be put
+ // back.
+ const $originalGroup = $group;
+ let dir;
- // Move available buttons between their container and the active
- // toolbar.
- if (containerType === 'source') {
- // Move the button to the active toolbar configuration when the down
- // or up keys are pressed.
- if (_.indexOf([40, 63233], event.keyCode) > -1) {
- // Move the button to the first row, first button group index
- // position.
- $activeButtons.find('.ckeditor-toolbar-group-buttons').eq(0).prepend($button);
- }
- }
- else if (containerType === 'target') {
- // Move buttons between sibling buttons in a group and between groups.
- if (_.indexOf(leftRightKeys, event.keyCode) > -1) {
- // Move left.
- const $siblings = $container.children();
- const index = $siblings.index($button);
- if (_.indexOf([37, 63234], event.keyCode) > -1) {
- // Move between sibling buttons.
- if (index > 0) {
- $button.insertBefore($container.children().eq(index - 1));
+ // Move available buttons between their container and the active
+ // toolbar.
+ if (containerType === 'source') {
+ // Move the button to the active toolbar configuration when the down
+ // or up keys are pressed.
+ if (_.indexOf([40, 63233], event.keyCode) > -1) {
+ // Move the button to the first row, first button group index
+ // position.
+ $activeButtons
+ .find('.ckeditor-toolbar-group-buttons')
+ .eq(0)
+ .prepend($button);
+ }
+ } else if (containerType === 'target') {
+ // Move buttons between sibling buttons in a group and between groups.
+ if (_.indexOf(leftRightKeys, event.keyCode) > -1) {
+ // Move left.
+ const $siblings = $container.children();
+ const index = $siblings.index($button);
+ if (_.indexOf([37, 63234], event.keyCode) > -1) {
+ // Move between sibling buttons.
+ if (index > 0) {
+ $button.insertBefore($container.children().eq(index - 1));
+ }
+ // Move between button groups and rows.
+ else {
+ // Move between button groups.
+ $group = $container.parent().prev();
+ if ($group.length > 0) {
+ $group
+ .find('.ckeditor-toolbar-group-buttons')
+ .append($button);
+ }
+ // Wrap between rows.
+ else {
+ $container
+ .closest('.ckeditor-row')
+ .prev()
+ .find('.ckeditor-toolbar-group')
+ .not('.placeholder')
+ .find('.ckeditor-toolbar-group-buttons')
+ .eq(-1)
+ .append($button);
+ }
+ }
}
- // Move between button groups and rows.
- else {
- // Move between button groups.
- $group = $container.parent().prev();
- if ($group.length > 0) {
- $group.find('.ckeditor-toolbar-group-buttons').append($button);
+ // Move right.
+ else if (_.indexOf([39, 63235], event.keyCode) > -1) {
+ // Move between sibling buttons.
+ if (index < $siblings.length - 1) {
+ $button.insertAfter($container.children().eq(index + 1));
}
- // Wrap between rows.
+ // Move between button groups. Moving right at the end of a row
+ // will create a new group.
else {
$container
- .closest('.ckeditor-row')
- .prev()
- .find('.ckeditor-toolbar-group')
- .not('.placeholder')
+ .parent()
+ .next()
.find('.ckeditor-toolbar-group-buttons')
- .eq(-1)
- .append($button);
+ .prepend($button);
}
}
}
- // Move right.
- else if (_.indexOf([39, 63235], event.keyCode) > -1) {
- // Move between sibling buttons.
- if (index < ($siblings.length - 1)) {
- $button.insertAfter($container.children().eq(index + 1));
- }
- // Move between button groups. Moving right at the end of a row
- // will create a new group.
- else {
- $container.parent().next().find('.ckeditor-toolbar-group-buttons').prepend($button);
- }
- }
- }
- // Move buttons between rows and the available button set.
- else if (_.indexOf(upDownKeys, event.keyCode) > -1) {
- dir = (_.indexOf([38, 63232], event.keyCode) > -1) ? 'prev' : 'next';
- $row = $container.closest('.ckeditor-row')[dir]();
- // Move the button back into the available button set.
- if (dir === 'prev' && $row.length === 0) {
- // If this is a divider, just destroy it.
- if ($button.data('drupal-ckeditor-type') === 'separator') {
- $button
- .off()
- .remove();
- // Focus on the first button in the active toolbar.
- $activeButtons
+ // Move buttons between rows and the available button set.
+ else if (_.indexOf(upDownKeys, event.keyCode) > -1) {
+ dir =
+ _.indexOf([38, 63232], event.keyCode) > -1 ? 'prev' : 'next';
+ $row = $container.closest('.ckeditor-row')[dir]();
+ // Move the button back into the available button set.
+ if (dir === 'prev' && $row.length === 0) {
+ // If this is a divider, just destroy it.
+ if ($button.data('drupal-ckeditor-type') === 'separator') {
+ $button.off().remove();
+ // Focus on the first button in the active toolbar.
+ $activeButtons
+ .find('.ckeditor-toolbar-group-buttons')
+ .eq(0)
+ .children()
+ .eq(0)
+ .children()
+ .trigger('focus');
+ }
+ // Otherwise, move it.
+ else {
+ $availableButtons.prepend($button);
+ }
+ } else {
+ $row
.find('.ckeditor-toolbar-group-buttons')
.eq(0)
- .children()
- .eq(0)
- .children()
- .trigger('focus');
+ .prepend($button);
}
- // Otherwise, move it.
- else {
- $availableButtons.prepend($button);
- }
- }
- else {
- $row.find('.ckeditor-toolbar-group-buttons').eq(0).prepend($button);
}
}
- }
- // Move dividers between their container and the active toolbar.
- else if (containerType === 'dividers') {
- // Move the button to the active toolbar configuration when the down
- // or up keys are pressed.
- if (_.indexOf([40, 63233], event.keyCode) > -1) {
- // Move the button to the first row, first button group index
- // position.
- $button = $button.clone(true);
- $activeButtons.find('.ckeditor-toolbar-group-buttons').eq(0).prepend($button);
- $target = $button.children();
+ // Move dividers between their container and the active toolbar.
+ else if (containerType === 'dividers') {
+ // Move the button to the active toolbar configuration when the down
+ // or up keys are pressed.
+ if (_.indexOf([40, 63233], event.keyCode) > -1) {
+ // Move the button to the first row, first button group index
+ // position.
+ $button = $button.clone(true);
+ $activeButtons
+ .find('.ckeditor-toolbar-group-buttons')
+ .eq(0)
+ .prepend($button);
+ $target = $button.children();
+ }
}
- }
- view = this;
- // Attempt to move the button to the new toolbar position.
- Drupal.ckeditor.registerButtonMove(this, $button, (result) => {
- // Put the button back if the registration failed.
- // If the button was in a row, then it was in the active toolbar
- // configuration. The button was probably placed in a new group, but
- // that action was canceled.
- if (!result && $originalGroup) {
- $originalGroup.find('.ckeditor-buttons').append($button);
- }
- // Otherwise refresh the sortables to acknowledge the new button
- // positions.
- else {
- view.$el.find('.ui-sortable').sortable('refresh');
- }
- // Refocus the target button so that the user can continue from a
- // known place.
- $target.trigger('focus');
- });
+ view = this;
+ // Attempt to move the button to the new toolbar position.
+ Drupal.ckeditor.registerButtonMove(this, $button, result => {
+ // Put the button back if the registration failed.
+ // If the button was in a row, then it was in the active toolbar
+ // configuration. The button was probably placed in a new group, but
+ // that action was canceled.
+ if (!result && $originalGroup) {
+ $originalGroup.find('.ckeditor-buttons').append($button);
+ }
+ // Otherwise refresh the sortables to acknowledge the new button
+ // positions.
+ else {
+ view.$el.find('.ui-sortable').sortable('refresh');
+ }
+ // Refocus the target button so that the user can continue from a
+ // known place.
+ $target.trigger('focus');
+ });
- event.preventDefault();
- event.stopPropagation();
- }
- },
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ },
- /**
- * Handles keypresses on a CKEditor configuration group.
- *
- * @param {jQuery.Event} event
- * The keypress event triggered.
- */
- onPressGroup(event) {
- const upDownKeys = [
- 38, // Up arrow.
- 63232, // Safari up arrow.
- 40, // Down arrow.
- 63233, // Safari down arrow.
- ];
- const leftRightKeys = [
- 37, // Left arrow.
- 63234, // Safari left arrow.
- 39, // Right arrow.
- 63235, // Safari right arrow.
- ];
+ /**
+ * Handles keypresses on a CKEditor configuration group.
+ *
+ * @param {jQuery.Event} event
+ * The keypress event triggered.
+ */
+ onPressGroup(event) {
+ const upDownKeys = [
+ 38, // Up arrow.
+ 63232, // Safari up arrow.
+ 40, // Down arrow.
+ 63233, // Safari down arrow.
+ ];
+ const leftRightKeys = [
+ 37, // Left arrow.
+ 63234, // Safari left arrow.
+ 39, // Right arrow.
+ 63235, // Safari right arrow.
+ ];
- // Respond to an enter key press.
- if (event.keyCode === 13) {
- const view = this;
- // Open the group renaming dialog in the next evaluation cycle so that
- // this event can be cancelled and the bubbling wiped out. Otherwise,
- // Firefox has issues because the page focus is shifted to the dialog
- // along with the keydown event.
- window.setTimeout(() => {
- Drupal.ckeditor.openGroupNameDialog(view, $(event.currentTarget));
- }, 0);
- event.preventDefault();
- event.stopPropagation();
- }
+ // Respond to an enter key press.
+ if (event.keyCode === 13) {
+ const view = this;
+ // Open the group renaming dialog in the next evaluation cycle so that
+ // this event can be cancelled and the bubbling wiped out. Otherwise,
+ // Firefox has issues because the page focus is shifted to the dialog
+ // along with the keydown event.
+ window.setTimeout(() => {
+ Drupal.ckeditor.openGroupNameDialog(view, $(event.currentTarget));
+ }, 0);
+ event.preventDefault();
+ event.stopPropagation();
+ }
- // Respond to direction key presses.
- if (_.indexOf(_.union(upDownKeys, leftRightKeys), event.keyCode) > -1) {
- const $group = $(event.currentTarget);
- const $container = $group.parent();
- const $siblings = $container.children();
- let index;
- let dir;
- // Move groups between sibling groups.
- if (_.indexOf(leftRightKeys, event.keyCode) > -1) {
- index = $siblings.index($group);
- // Move left between sibling groups.
- if ((_.indexOf([37, 63234], event.keyCode) > -1)) {
- if (index > 0) {
- $group.insertBefore($siblings.eq(index - 1));
+ // Respond to direction key presses.
+ if (_.indexOf(_.union(upDownKeys, leftRightKeys), event.keyCode) > -1) {
+ const $group = $(event.currentTarget);
+ const $container = $group.parent();
+ const $siblings = $container.children();
+ let index;
+ let dir;
+ // Move groups between sibling groups.
+ if (_.indexOf(leftRightKeys, event.keyCode) > -1) {
+ index = $siblings.index($group);
+ // Move left between sibling groups.
+ if (_.indexOf([37, 63234], event.keyCode) > -1) {
+ if (index > 0) {
+ $group.insertBefore($siblings.eq(index - 1));
+ }
+ // Wrap between rows. Insert the group before the placeholder group
+ // at the end of the previous row.
+ else {
+ const $rowChildElement = $container
+ .closest('.ckeditor-row')
+ .prev()
+ .find('.ckeditor-toolbar-groups')
+ .children()
+ .eq(-1);
+ $group.insertBefore($rowChildElement);
+ }
}
- // Wrap between rows. Insert the group before the placeholder group
- // at the end of the previous row.
- else {
- const $rowChildElement = $container
- .closest('.ckeditor-row')
- .prev()
- .find('.ckeditor-toolbar-groups')
- .children()
- .eq(-1);
- $group.insertBefore($rowChildElement);
+ // Move right between sibling groups.
+ else if (_.indexOf([39, 63235], event.keyCode) > -1) {
+ // Move to the right if the next group is not a placeholder.
+ if (!$siblings.eq(index + 1).hasClass('placeholder')) {
+ $group.insertAfter($container.children().eq(index + 1));
+ }
+ // Wrap group between rows.
+ else {
+ $container
+ .closest('.ckeditor-row')
+ .next()
+ .find('.ckeditor-toolbar-groups')
+ .prepend($group);
+ }
}
}
- // Move right between sibling groups.
- else if (_.indexOf([39, 63235], event.keyCode) > -1) {
- // Move to the right if the next group is not a placeholder.
- if (!$siblings.eq(index + 1).hasClass('placeholder')) {
- $group.insertAfter($container.children().eq(index + 1));
- }
- // Wrap group between rows.
- else {
- $container.closest('.ckeditor-row').next().find('.ckeditor-toolbar-groups').prepend($group);
- }
+ // Move groups between rows.
+ else if (_.indexOf(upDownKeys, event.keyCode) > -1) {
+ dir = _.indexOf([38, 63232], event.keyCode) > -1 ? 'prev' : 'next';
+ $group
+ .closest('.ckeditor-row')
+ [dir]()
+ .find('.ckeditor-toolbar-groups')
+ .eq(0)
+ .prepend($group);
}
- }
- // Move groups between rows.
- else if (_.indexOf(upDownKeys, event.keyCode) > -1) {
- dir = (_.indexOf([38, 63232], event.keyCode) > -1) ? 'prev' : 'next';
- $group
- .closest('.ckeditor-row')[dir]()
- .find('.ckeditor-toolbar-groups')
- .eq(0)
- .prepend($group);
- }
- Drupal.ckeditor.registerGroupMove(this, $group);
- $group.trigger('focus');
- event.preventDefault();
- event.stopPropagation();
- }
+ Drupal.ckeditor.registerGroupMove(this, $group);
+ $group.trigger('focus');
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ },
},
- });
-}(jQuery, Drupal, Backbone, _));
+ );
+})(jQuery, Drupal, Backbone, _);
diff --git a/core/modules/ckeditor/js/views/VisualView.es6.js b/core/modules/ckeditor/js/views/VisualView.es6.js
index 413e69b..a7304f9 100644
--- a/core/modules/ckeditor/js/views/VisualView.es6.js
+++ b/core/modules/ckeditor/js/views/VisualView.es6.js
@@ -4,265 +4,312 @@
* configuration.
*/
-(function (Drupal, Backbone, $) {
- Drupal.ckeditor.VisualView = Backbone.View.extend(/** @lends Drupal.ckeditor.VisualView# */{
+(function(Drupal, Backbone, $) {
+ Drupal.ckeditor.VisualView = Backbone.View.extend(
+ /** @lends Drupal.ckeditor.VisualView# */ {
+ events: {
+ 'click .ckeditor-toolbar-group-name': 'onGroupNameClick',
+ 'click .ckeditor-groupnames-toggle': 'onGroupNamesToggleClick',
+ 'click .ckeditor-add-new-group button': 'onAddGroupButtonClick',
+ },
- events: {
- 'click .ckeditor-toolbar-group-name': 'onGroupNameClick',
- 'click .ckeditor-groupnames-toggle': 'onGroupNamesToggleClick',
- 'click .ckeditor-add-new-group button': 'onAddGroupButtonClick',
- },
+ /**
+ * Backbone View for CKEditor toolbar configuration; visual UX.
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ this.listenTo(
+ this.model,
+ 'change:isDirty change:groupNamesVisible',
+ this.render,
+ );
- /**
- * Backbone View for CKEditor toolbar configuration; visual UX.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- this.listenTo(this.model, 'change:isDirty change:groupNamesVisible', this.render);
+ // Add a toggle for the button group names.
+ $(Drupal.theme('ckeditorButtonGroupNamesToggle')).prependTo(
+ this.$el.find('#ckeditor-active-toolbar').parent(),
+ );
- // Add a toggle for the button group names.
- $(Drupal.theme('ckeditorButtonGroupNamesToggle'))
- .prependTo(this.$el.find('#ckeditor-active-toolbar').parent());
+ this.render();
+ },
- this.render();
- },
+ /**
+ * Render function for rendering the toolbar configuration.
+ *
+ * @param {*} model
+ * Model used for the view.
+ * @param {string} [value]
+ * The value that was changed.
+ * @param {object} changedAttributes
+ * The attributes that was changed.
+ *
+ * @return {Drupal.ckeditor.VisualView}
+ * The {@link Drupal.ckeditor.VisualView} object.
+ */
+ render(model, value, changedAttributes) {
+ this.insertPlaceholders();
+ this.applySorting();
- /**
- * Render function for rendering the toolbar configuration.
- *
- * @param {*} model
- * Model used for the view.
- * @param {string} [value]
- * The value that was changed.
- * @param {object} changedAttributes
- * The attributes that was changed.
- *
- * @return {Drupal.ckeditor.VisualView}
- * The {@link Drupal.ckeditor.VisualView} object.
- */
- render(model, value, changedAttributes) {
- this.insertPlaceholders();
- this.applySorting();
+ // Toggle button group names.
+ let groupNamesVisible = this.model.get('groupNamesVisible');
+ // If a button was just placed in the active toolbar, ensure that the
+ // button group names are visible.
+ if (
+ changedAttributes &&
+ changedAttributes.changes &&
+ changedAttributes.changes.isDirty
+ ) {
+ this.model.set({ groupNamesVisible: true }, { silent: true });
+ groupNamesVisible = true;
+ }
+ this.$el
+ .find('[data-toolbar="active"]')
+ .toggleClass('ckeditor-group-names-are-visible', groupNamesVisible);
+ this.$el
+ .find('.ckeditor-groupnames-toggle')
+ .text(
+ groupNamesVisible
+ ? Drupal.t('Hide group names')
+ : Drupal.t('Show group names'),
+ )
+ .attr('aria-pressed', groupNamesVisible);
- // Toggle button group names.
- let groupNamesVisible = this.model.get('groupNamesVisible');
- // If a button was just placed in the active toolbar, ensure that the
- // button group names are visible.
- if (changedAttributes && changedAttributes.changes && changedAttributes.changes.isDirty) {
- this.model.set({ groupNamesVisible: true }, { silent: true });
- groupNamesVisible = true;
- }
- this.$el.find('[data-toolbar="active"]').toggleClass('ckeditor-group-names-are-visible', groupNamesVisible);
- this.$el.find('.ckeditor-groupnames-toggle')
- .text((groupNamesVisible) ? Drupal.t('Hide group names') : Drupal.t('Show group names'))
- .attr('aria-pressed', groupNamesVisible);
+ return this;
+ },
- return this;
- },
+ /**
+ * Handles clicks to a button group name.
+ *
+ * @param {jQuery.Event} event
+ * The click event on the button group.
+ */
+ onGroupNameClick(event) {
+ const $group = $(event.currentTarget).closest(
+ '.ckeditor-toolbar-group',
+ );
+ Drupal.ckeditor.openGroupNameDialog(this, $group);
- /**
- * Handles clicks to a button group name.
- *
- * @param {jQuery.Event} event
- * The click event on the button group.
- */
- onGroupNameClick(event) {
- const $group = $(event.currentTarget).closest('.ckeditor-toolbar-group');
- Drupal.ckeditor.openGroupNameDialog(this, $group);
+ event.stopPropagation();
+ event.preventDefault();
+ },
- event.stopPropagation();
- event.preventDefault();
- },
-
- /**
- * Handles clicks on the button group names toggle button.
- *
- * @param {jQuery.Event} event
- * The click event on the toggle button.
- */
- onGroupNamesToggleClick(event) {
- this.model.set('groupNamesVisible', !this.model.get('groupNamesVisible'));
- event.preventDefault();
- },
+ /**
+ * Handles clicks on the button group names toggle button.
+ *
+ * @param {jQuery.Event} event
+ * The click event on the toggle button.
+ */
+ onGroupNamesToggleClick(event) {
+ this.model.set(
+ 'groupNamesVisible',
+ !this.model.get('groupNamesVisible'),
+ );
+ event.preventDefault();
+ },
- /**
- * Prompts the user to provide a name for a new button group; inserts it.
- *
- * @param {jQuery.Event} event
- * The event of the button click.
- */
- onAddGroupButtonClick(event) {
/**
- * Inserts a new button if the openGroupNameDialog function returns true.
+ * Prompts the user to provide a name for a new button group; inserts it.
*
- * @param {bool} success
- * A flag that indicates if the user created a new group (true) or
- * canceled out of the dialog (false).
- * @param {jQuery} $group
- * A jQuery DOM fragment that represents the new button group. It has
- * not been added to the DOM yet.
+ * @param {jQuery.Event} event
+ * The event of the button click.
*/
- function insertNewGroup(success, $group) {
- if (success) {
- $group.appendTo($(event.currentTarget).closest('.ckeditor-row').children('.ckeditor-toolbar-groups'));
- // Focus on the new group.
- $group.trigger('focus');
+ onAddGroupButtonClick(event) {
+ /**
+ * Inserts a new button if the openGroupNameDialog function returns true.
+ *
+ * @param {bool} success
+ * A flag that indicates if the user created a new group (true) or
+ * canceled out of the dialog (false).
+ * @param {jQuery} $group
+ * A jQuery DOM fragment that represents the new button group. It has
+ * not been added to the DOM yet.
+ */
+ function insertNewGroup(success, $group) {
+ if (success) {
+ $group.appendTo(
+ $(event.currentTarget)
+ .closest('.ckeditor-row')
+ .children('.ckeditor-toolbar-groups'),
+ );
+ // Focus on the new group.
+ $group.trigger('focus');
+ }
}
- }
- // Pass in a DOM fragment of a placeholder group so that the new group
- // name can be applied to it.
- Drupal.ckeditor.openGroupNameDialog(this, $(Drupal.theme('ckeditorToolbarGroup')), insertNewGroup);
+ // Pass in a DOM fragment of a placeholder group so that the new group
+ // name can be applied to it.
+ Drupal.ckeditor.openGroupNameDialog(
+ this,
+ $(Drupal.theme('ckeditorToolbarGroup')),
+ insertNewGroup,
+ );
- event.preventDefault();
- },
+ event.preventDefault();
+ },
- /**
- * Handles jQuery Sortable stop sort of a button group.
- *
- * @param {jQuery.Event} event
- * The event triggered on the group drag.
- * @param {object} ui
- * A jQuery.ui.sortable argument that contains information about the
- * elements involved in the sort action.
- */
- endGroupDrag(event, ui) {
- const view = this;
- Drupal.ckeditor.registerGroupMove(this, ui.item, (success) => {
- if (!success) {
- // Cancel any sorting in the configuration area.
- view.$el.find('.ckeditor-toolbar-configuration').find('.ui-sortable').sortable('cancel');
- }
- });
- },
+ /**
+ * Handles jQuery Sortable stop sort of a button group.
+ *
+ * @param {jQuery.Event} event
+ * The event triggered on the group drag.
+ * @param {object} ui
+ * A jQuery.ui.sortable argument that contains information about the
+ * elements involved in the sort action.
+ */
+ endGroupDrag(event, ui) {
+ const view = this;
+ Drupal.ckeditor.registerGroupMove(this, ui.item, success => {
+ if (!success) {
+ // Cancel any sorting in the configuration area.
+ view.$el
+ .find('.ckeditor-toolbar-configuration')
+ .find('.ui-sortable')
+ .sortable('cancel');
+ }
+ });
+ },
- /**
- * Handles jQuery Sortable start sort of a button.
- *
- * @param {jQuery.Event} event
- * The event triggered on the group drag.
- * @param {object} ui
- * A jQuery.ui.sortable argument that contains information about the
- * elements involved in the sort action.
- */
- startButtonDrag(event, ui) {
- this.$el.find('a:focus').trigger('blur');
+ /**
+ * Handles jQuery Sortable start sort of a button.
+ *
+ * @param {jQuery.Event} event
+ * The event triggered on the group drag.
+ * @param {object} ui
+ * A jQuery.ui.sortable argument that contains information about the
+ * elements involved in the sort action.
+ */
+ startButtonDrag(event, ui) {
+ this.$el.find('a:focus').trigger('blur');
- // Show the button group names as soon as the user starts dragging.
- this.model.set('groupNamesVisible', true);
- },
+ // Show the button group names as soon as the user starts dragging.
+ this.model.set('groupNamesVisible', true);
+ },
- /**
- * Handles jQuery Sortable stop sort of a button.
- *
- * @param {jQuery.Event} event
- * The event triggered on the button drag.
- * @param {object} ui
- * A jQuery.ui.sortable argument that contains information about the
- * elements involved in the sort action.
- */
- endButtonDrag(event, ui) {
- const view = this;
- Drupal.ckeditor.registerButtonMove(this, ui.item, (success) => {
- if (!success) {
- // Cancel any sorting in the configuration area.
- view.$el.find('.ui-sortable').sortable('cancel');
- }
- // Refocus the target button so that the user can continue from a known
- // place.
- ui.item.find('a').trigger('focus');
- });
- },
+ /**
+ * Handles jQuery Sortable stop sort of a button.
+ *
+ * @param {jQuery.Event} event
+ * The event triggered on the button drag.
+ * @param {object} ui
+ * A jQuery.ui.sortable argument that contains information about the
+ * elements involved in the sort action.
+ */
+ endButtonDrag(event, ui) {
+ const view = this;
+ Drupal.ckeditor.registerButtonMove(this, ui.item, success => {
+ if (!success) {
+ // Cancel any sorting in the configuration area.
+ view.$el.find('.ui-sortable').sortable('cancel');
+ }
+ // Refocus the target button so that the user can continue from a known
+ // place.
+ ui.item.find('a').trigger('focus');
+ });
+ },
- /**
- * Invokes jQuery.sortable() on new buttons and groups in a CKEditor config.
- */
- applySorting() {
- // Make the buttons sortable.
- this.$el.find('.ckeditor-buttons').not('.ui-sortable').sortable({
- // Change this to .ckeditor-toolbar-group-buttons.
- connectWith: '.ckeditor-buttons',
- placeholder: 'ckeditor-button-placeholder',
- forcePlaceholderSize: true,
- tolerance: 'pointer',
- cursor: 'move',
- start: this.startButtonDrag.bind(this),
- // Sorting within a sortable.
- stop: this.endButtonDrag.bind(this),
- }).disableSelection();
+ /**
+ * Invokes jQuery.sortable() on new buttons and groups in a CKEditor config.
+ */
+ applySorting() {
+ // Make the buttons sortable.
+ this.$el
+ .find('.ckeditor-buttons')
+ .not('.ui-sortable')
+ .sortable({
+ // Change this to .ckeditor-toolbar-group-buttons.
+ connectWith: '.ckeditor-buttons',
+ placeholder: 'ckeditor-button-placeholder',
+ forcePlaceholderSize: true,
+ tolerance: 'pointer',
+ cursor: 'move',
+ start: this.startButtonDrag.bind(this),
+ // Sorting within a sortable.
+ stop: this.endButtonDrag.bind(this),
+ })
+ .disableSelection();
- // Add the drag and drop functionality to button groups.
- this.$el.find('.ckeditor-toolbar-groups').not('.ui-sortable').sortable({
- connectWith: '.ckeditor-toolbar-groups',
- cancel: '.ckeditor-add-new-group',
- placeholder: 'ckeditor-toolbar-group-placeholder',
- forcePlaceholderSize: true,
- cursor: 'move',
- stop: this.endGroupDrag.bind(this),
- });
+ // Add the drag and drop functionality to button groups.
+ this.$el
+ .find('.ckeditor-toolbar-groups')
+ .not('.ui-sortable')
+ .sortable({
+ connectWith: '.ckeditor-toolbar-groups',
+ cancel: '.ckeditor-add-new-group',
+ placeholder: 'ckeditor-toolbar-group-placeholder',
+ forcePlaceholderSize: true,
+ cursor: 'move',
+ stop: this.endGroupDrag.bind(this),
+ });
- // Add the drag and drop functionality to buttons.
- this.$el.find('.ckeditor-multiple-buttons li').draggable({
- connectToSortable: '.ckeditor-toolbar-active .ckeditor-buttons',
- helper: 'clone',
- });
- },
+ // Add the drag and drop functionality to buttons.
+ this.$el.find('.ckeditor-multiple-buttons li').draggable({
+ connectToSortable: '.ckeditor-toolbar-active .ckeditor-buttons',
+ helper: 'clone',
+ });
+ },
- /**
- * Wraps the invocation of methods to insert blank groups and rows.
- */
- insertPlaceholders() {
- this.insertPlaceholderRow();
- this.insertNewGroupButtons();
- },
+ /**
+ * Wraps the invocation of methods to insert blank groups and rows.
+ */
+ insertPlaceholders() {
+ this.insertPlaceholderRow();
+ this.insertNewGroupButtons();
+ },
- /**
- * Inserts a blank row at the bottom of the CKEditor configuration.
- */
- insertPlaceholderRow() {
- let $rows = this.$el.find('.ckeditor-row');
- // Add a placeholder row. to the end of the list if one does not exist.
- if (!$rows.eq(-1).hasClass('placeholder')) {
- this.$el
- .find('.ckeditor-toolbar-active')
- .children('.ckeditor-active-toolbar-configuration')
- .append(Drupal.theme('ckeditorRow'));
- }
- // Update the $rows variable to include the new row.
- $rows = this.$el.find('.ckeditor-row');
- // Remove blank rows except the last one.
- const len = $rows.length;
- $rows.filter((index, row) => {
- // Do not remove the last row.
- if (index + 1 === len) {
- return false;
+ /**
+ * Inserts a blank row at the bottom of the CKEditor configuration.
+ */
+ insertPlaceholderRow() {
+ let $rows = this.$el.find('.ckeditor-row');
+ // Add a placeholder row. to the end of the list if one does not exist.
+ if (!$rows.eq(-1).hasClass('placeholder')) {
+ this.$el
+ .find('.ckeditor-toolbar-active')
+ .children('.ckeditor-active-toolbar-configuration')
+ .append(Drupal.theme('ckeditorRow'));
}
- return $(row).find('.ckeditor-toolbar-group').not('.placeholder').length === 0;
- })
- // Then get all rows that are placeholders and remove them.
- .remove();
- },
+ // Update the $rows variable to include the new row.
+ $rows = this.$el.find('.ckeditor-row');
+ // Remove blank rows except the last one.
+ const len = $rows.length;
+ $rows
+ .filter((index, row) => {
+ // Do not remove the last row.
+ if (index + 1 === len) {
+ return false;
+ }
+ return (
+ $(row)
+ .find('.ckeditor-toolbar-group')
+ .not('.placeholder').length === 0
+ );
+ })
+ // Then get all rows that are placeholders and remove them.
+ .remove();
+ },
- /**
- * Inserts a button in each row that will add a new CKEditor button group.
- */
- insertNewGroupButtons() {
- // Insert an add group button to each row.
- this.$el.find('.ckeditor-row').each(function () {
- const $row = $(this);
- const $groups = $row.find('.ckeditor-toolbar-group');
- const $button = $row.find('.ckeditor-add-new-group');
- if ($button.length === 0) {
- $row.children('.ckeditor-toolbar-groups').append(Drupal.theme('ckeditorNewButtonGroup'));
- }
- // If a placeholder group exists, make sure it's at the end of the row.
- else if (!$groups.eq(-1).hasClass('ckeditor-add-new-group')) {
- $button.appendTo($row.children('.ckeditor-toolbar-groups'));
- }
- });
+ /**
+ * Inserts a button in each row that will add a new CKEditor button group.
+ */
+ insertNewGroupButtons() {
+ // Insert an add group button to each row.
+ this.$el.find('.ckeditor-row').each(function() {
+ const $row = $(this);
+ const $groups = $row.find('.ckeditor-toolbar-group');
+ const $button = $row.find('.ckeditor-add-new-group');
+ if ($button.length === 0) {
+ $row
+ .children('.ckeditor-toolbar-groups')
+ .append(Drupal.theme('ckeditorNewButtonGroup'));
+ }
+ // If a placeholder group exists, make sure it's at the end of the row.
+ else if (!$groups.eq(-1).hasClass('ckeditor-add-new-group')) {
+ $button.appendTo($row.children('.ckeditor-toolbar-groups'));
+ }
+ });
+ },
},
- });
-}(Drupal, Backbone, jQuery));
+ );
+})(Drupal, Backbone, jQuery);
diff --git a/core/modules/ckeditor/js/views/VisualView.js b/core/modules/ckeditor/js/views/VisualView.js
index 9808015..a5ebbdf 100644
--- a/core/modules/ckeditor/js/views/VisualView.js
+++ b/core/modules/ckeditor/js/views/VisualView.js
@@ -7,7 +7,6 @@
(function (Drupal, Backbone, $) {
Drupal.ckeditor.VisualView = Backbone.View.extend({
-
events: {
'click .ckeditor-toolbar-group-name': 'onGroupNameClick',
'click .ckeditor-groupnames-toggle': 'onGroupNamesToggleClick',
diff --git a/core/modules/ckeditor/tests/modules/js/ajax-css.es6.js b/core/modules/ckeditor/tests/modules/js/ajax-css.es6.js
index af97a3b..532ec44 100644
--- a/core/modules/ckeditor/tests/modules/js/ajax-css.es6.js
+++ b/core/modules/ckeditor/tests/modules/js/ajax-css.es6.js
@@ -3,18 +3,17 @@
* Contains client-side code for testing CSS delivered to CKEditor via AJAX.
*/
-(function (Drupal, ckeditor, editorSettings, $) {
+(function(Drupal, ckeditor, editorSettings, $) {
Drupal.behaviors.ajaxCssForm = {
-
attach(context) {
// Initialize an inline CKEditor on the #edit-inline element if it
// isn't editable already.
$(context)
.find('#edit-inline')
.not('[contenteditable]')
- .each(function () {
+ .each(function() {
ckeditor.attachInlineEditor(this, editorSettings.formats.test_format);
});
},
};
-}(Drupal, Drupal.editors.ckeditor, drupalSettings.editor, jQuery));
+})(Drupal, Drupal.editors.ckeditor, drupalSettings.editor, jQuery);
diff --git a/core/modules/color/color.es6.js b/core/modules/color/color.es6.js
index 809c15e..bff417c 100644
--- a/core/modules/color/color.es6.js
+++ b/core/modules/color/color.es6.js
@@ -3,7 +3,7 @@
* Attaches the behaviors for the Color module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Displays farbtastic color selector and initialize color administration UI.
*
@@ -18,7 +18,9 @@
let j;
let colors;
// This behavior attaches by ID, so is only valid once on a page.
- const form = $(context).find('#system-theme-settings .color-form').once('color');
+ const form = $(context)
+ .find('#system-theme-settings .color-form')
+ .once('color');
if (form.length === 0) {
return;
}
@@ -28,12 +30,14 @@
let focused = null;
// Add Farbtastic.
- $('<div class="color-placeholder"></div>').once('color').prependTo(form);
+ $('<div class="color-placeholder"></div>')
+ .once('color')
+ .prependTo(form);
const farb = $.farbtastic('.color-placeholder');
// Decode reference colors to HSL.
const reference = settings.color.reference;
- Object.keys(reference || {}).forEach((color) => {
+ Object.keys(reference || {}).forEach(color => {
reference[color] = farb.RGBToHSL(farb.unpack(reference[color]));
});
@@ -52,7 +56,7 @@
* Resets the color scheme selector.
*/
function resetScheme() {
- form.find('#edit-scheme').each(function () {
+ form.find('#edit-scheme').each(function() {
this.selectedIndex = this.options.length - 1;
});
}
@@ -89,28 +93,24 @@
// Saturation: interpolate.
if (ref1[1] === 0 || ref2[1] === 0) {
given[1] = ref2[1];
- }
- else {
+ } else {
d = ref1[1] / ref2[1];
if (d > 1) {
given[1] /= d;
- }
- else {
- given[1] = 1 - ((1 - given[1]) * d);
+ } else {
+ given[1] = 1 - (1 - given[1]) * d;
}
}
// Luminance: interpolate.
if (ref1[2] === 0 || ref2[2] === 0) {
given[2] = ref2[2];
- }
- else {
+ } else {
d = ref1[2] / ref2[2];
if (d > 1) {
given[2] /= d;
- }
- else {
- given[2] = 1 - ((1 - given[2]) * d);
+ } else {
+ given[2] = 1 - (1 - given[2]) * d;
}
}
@@ -149,14 +149,22 @@
if (!locks[j - 1] || $(locks[j - 1]).is('.is-unlocked')) {
break;
}
- matched = shiftColor(color, reference[input.key], reference[inputs[j].key]);
+ matched = shiftColor(
+ color,
+ reference[input.key],
+ reference[inputs[j].key],
+ );
callback(inputs[j], matched, false);
}
for (j = i - 1; ; --j) {
if (!locks[j] || $(locks[j]).is('.is-unlocked')) {
break;
}
- matched = shiftColor(color, reference[input.key], reference[inputs[j].key]);
+ matched = shiftColor(
+ color,
+ reference[input.key],
+ reference[inputs[j].key],
+ );
callback(inputs[j], matched, false);
}
@@ -172,9 +180,11 @@
}
// Loop through all defined gradients.
- Object.keys(settings.gradients || {}).forEach((i) => {
+ Object.keys(settings.gradients || {}).forEach(i => {
// Add element to display the gradient.
- $('.color-preview').once('color').append(`<div id="gradient-${i}"></div>`);
+ $('.color-preview')
+ .once('color')
+ .append(`<div id="gradient-${i}"></div>`);
const gradient = $(`.color-preview #gradient-${i}`);
// Add height of current gradient to the list (divided by 10).
height.push(parseInt(gradient.css('height'), 10) / 10);
@@ -184,20 +194,32 @@
// Each gradient line should have a height (or width for horizontal
// gradients) of 10px (because we divided the height/width by 10
// above).
- for (j = 0; j < (settings.gradients[i].direction === 'vertical' ? height[i] : width[i]); ++j) {
+ for (
+ j = 0;
+ j <
+ (settings.gradients[i].direction === 'vertical'
+ ? height[i]
+ : width[i]);
+ ++j
+ ) {
gradient.append('<div class="gradient-line"></div>');
}
});
// Set up colorScheme selector.
- form.find('#edit-scheme').on('change', function () {
+ form.find('#edit-scheme').on('change', function() {
const schemes = settings.color.schemes;
const colorScheme = this.options[this.selectedIndex].value;
if (colorScheme !== '' && schemes[colorScheme]) {
// Get colors of active scheme.
colors = schemes[colorScheme];
- Object.keys(colors || {}).forEach((fieldName) => {
- callback($(`#edit-palette-${fieldName}`), colors[fieldName], false, true);
+ Object.keys(colors || {}).forEach(fieldName => {
+ callback(
+ $(`#edit-palette-${fieldName}`),
+ colors[fieldName],
+ false,
+ true,
+ );
});
preview();
}
@@ -223,7 +245,7 @@
// Add new bindings.
focused = input;
- farb.linkTo((color) => {
+ farb.linkTo(color => {
callback(input, color, true, false);
});
farb.setColor(input.value);
@@ -236,40 +258,59 @@
}
// Initialize color fields.
- form.find('.js-color-palette input.form-text')
- .each(function () {
+ form
+ .find('.js-color-palette input.form-text')
+ .each(function() {
// Extract palette field name.
this.key = this.id.substring(13);
// Link to color picker temporarily to initialize.
- farb.linkTo(() => {}).setColor('#000').linkTo(this);
+ farb
+ .linkTo(() => {})
+ .setColor('#000')
+ .linkTo(this);
// Add lock.
const i = inputs.length;
if (inputs.length) {
let toggleClick = true;
- const lock = $(`<button class="color-palette__lock">${Drupal.t('Unlock')}</button>`).on('click', function (e) {
+ const lock = $(
+ `<button class="color-palette__lock">${Drupal.t(
+ 'Unlock',
+ )}</button>`,
+ ).on('click', function(e) {
e.preventDefault();
if (toggleClick) {
- $(this).addClass('is-unlocked').html(Drupal.t('Lock'));
+ $(this)
+ .addClass('is-unlocked')
+ .html(Drupal.t('Lock'));
$(hooks[i - 1]).attr(
'class',
- locks[i - 2] && $(locks[i - 2]).is(':not(.is-unlocked)') ? 'color-palette__hook is-up' : 'color-palette__hook',
+ locks[i - 2] && $(locks[i - 2]).is(':not(.is-unlocked)')
+ ? 'color-palette__hook is-up'
+ : 'color-palette__hook',
);
$(hooks[i]).attr(
'class',
- locks[i] && $(locks[i]).is(':not(.is-unlocked)') ? 'color-palette__hook is-down' : 'color-palette__hook',
+ locks[i] && $(locks[i]).is(':not(.is-unlocked)')
+ ? 'color-palette__hook is-down'
+ : 'color-palette__hook',
);
- }
- else {
- $(this).removeClass('is-unlocked').html(Drupal.t('Unlock'));
+ } else {
+ $(this)
+ .removeClass('is-unlocked')
+ .html(Drupal.t('Unlock'));
$(hooks[i - 1]).attr(
'class',
- locks[i - 2] && $(locks[i - 2]).is(':not(.is-unlocked)') ? 'color-palette__hook is-both' : 'color-palette__hook is-down',
+ locks[i - 2] && $(locks[i - 2]).is(':not(.is-unlocked)')
+ ? 'color-palette__hook is-both'
+ : 'color-palette__hook is-down',
);
$(hooks[i]).attr(
'class',
- locks[i] && $(locks[i]).is(':not(.is-unlocked)') ? 'color-palette__hook is-both' : 'color-palette__hook is-up',
+ locks[i] && $(locks[i]).is(':not(.is-unlocked)')
+ ? 'color-palette__hook is-both'
+ : 'color-palette__hook is-up',
);
}
toggleClick = !toggleClick;
@@ -283,7 +324,10 @@
$(this).after(hook);
hooks.push(hook);
- $(this).parent().find('.color-palette__lock').trigger('click');
+ $(this)
+ .parent()
+ .find('.color-palette__lock')
+ .trigger('click');
this.i = i;
inputs.push(this);
})
@@ -298,4 +342,4 @@
preview();
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/color/preview.es6.js b/core/modules/color/preview.es6.js
index cfc5e76..f681dbe 100644
--- a/core/modules/color/preview.es6.js
+++ b/core/modules/color/preview.es6.js
@@ -3,14 +3,13 @@
* Attaches preview-related behavior for the Color module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Namespace for color-related functionality for Drupal.
*
* @namespace
*/
Drupal.color = {
-
/**
* The callback for when the color preview has been attached.
*
@@ -31,14 +30,29 @@
let accum;
let delta;
// Solid background.
- form.find('.color-preview').css('backgroundColor', form.find('.color-palette input[name="palette[base]"]').val());
+ form
+ .find('.color-preview')
+ .css(
+ 'backgroundColor',
+ form.find('.color-palette input[name="palette[base]"]').val(),
+ );
// Text preview.
- form.find('#text').css('color', form.find('.color-palette input[name="palette[text]"]').val());
- form.find('#text a, #text h2').css('color', form.find('.color-palette input[name="palette[link]"]').val());
+ form
+ .find('#text')
+ .css(
+ 'color',
+ form.find('.color-palette input[name="palette[text]"]').val(),
+ );
+ form
+ .find('#text a, #text h2')
+ .css(
+ 'color',
+ form.find('.color-palette input[name="palette[link]"]').val(),
+ );
function gradientLineColor(i, element) {
- Object.keys(accum || {}).forEach((k) => {
+ Object.keys(accum || {}).forEach(k => {
accum[k] += delta[k];
});
element.style.backgroundColor = farb.pack(accum);
@@ -47,13 +61,31 @@
// Set up gradients if there are some.
let colorStart;
let colorEnd;
- Object.keys(settings.gradients || {}).forEach((i) => {
- colorStart = farb.unpack(form.find(`.color-palette input[name="palette[${settings.gradients[i].colors[0]}]"]`).val());
- colorEnd = farb.unpack(form.find(`.color-palette input[name="palette[${settings.gradients[i].colors[1]}]"]`).val());
+ Object.keys(settings.gradients || {}).forEach(i => {
+ colorStart = farb.unpack(
+ form
+ .find(
+ `.color-palette input[name="palette[${
+ settings.gradients[i].colors[0]
+ }]"]`,
+ )
+ .val(),
+ );
+ colorEnd = farb.unpack(
+ form
+ .find(
+ `.color-palette input[name="palette[${
+ settings.gradients[i].colors[1]
+ }]"]`,
+ )
+ .val(),
+ );
if (colorStart && colorEnd) {
delta = [];
- Object.keys(colorStart || {}).forEach((colorStartKey) => {
- delta[colorStartKey] = (colorEnd[colorStartKey] - colorStart[colorStartKey]) / (settings.gradients[i].vertical ? height[i] : width[i]);
+ Object.keys(colorStart || {}).forEach(colorStartKey => {
+ delta[colorStartKey] =
+ (colorEnd[colorStartKey] - colorStart[colorStartKey]) /
+ (settings.gradients[i].vertical ? height[i] : width[i]);
});
accum = colorStart;
// Render gradient lines.
@@ -62,4 +94,4 @@
});
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/color/tests/modules/color_test/themes/color_test_theme/js/color_test_theme-fontsize.es6.js b/core/modules/color/tests/modules/color_test/themes/color_test_theme/js/color_test_theme-fontsize.es6.js
index 1095df1..33076ac 100644
--- a/core/modules/color/tests/modules/color_test/themes/color_test_theme/js/color_test_theme-fontsize.es6.js
+++ b/core/modules/color/tests/modules/color_test/themes/color_test_theme/js/color_test_theme-fontsize.es6.js
@@ -2,6 +2,6 @@
* @file
* Adds javascript functions for font resizing.
*/
-(function ($) {
+(function($) {
$(document).ready(() => {});
-}(jQuery));
+})(jQuery);
diff --git a/core/modules/comment/comment-entity-form.es6.js b/core/modules/comment/comment-entity-form.es6.js
index 00a3404..4f25c9b 100644
--- a/core/modules/comment/comment-entity-form.es6.js
+++ b/core/modules/comment/comment-entity-form.es6.js
@@ -3,7 +3,7 @@
* Attaches comment behaviors to the entity form.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
*
* @type {Drupal~behavior}
@@ -11,7 +11,16 @@
Drupal.behaviors.commentFieldsetSummaries = {
attach(context) {
const $context = $(context);
- $context.find('fieldset.comment-entity-settings-form').drupalSetSummary(context => Drupal.checkPlain($(context).find('.js-form-item-comment input:checked').next('label').text()));
+ $context
+ .find('fieldset.comment-entity-settings-form')
+ .drupalSetSummary(context =>
+ Drupal.checkPlain(
+ $(context)
+ .find('.js-form-item-comment input:checked')
+ .next('label')
+ .text(),
+ ),
+ );
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/comment/js/comment-by-viewer.es6.js b/core/modules/comment/js/comment-by-viewer.es6.js
index db56153..de24038 100644
--- a/core/modules/comment/js/comment-by-viewer.es6.js
+++ b/core/modules/comment/js/comment-by-viewer.es6.js
@@ -3,7 +3,7 @@
* Attaches behaviors for the Comment module's "by-viewer" class.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Add 'by-viewer' class to comments written by the current user.
*
@@ -13,10 +13,13 @@
attach(context) {
const currentUserID = parseInt(drupalSettings.user.uid, 10);
$('[data-comment-user-id]')
- .filter(function () {
- return parseInt(this.getAttribute('data-comment-user-id'), 10) === currentUserID;
+ .filter(function() {
+ return (
+ parseInt(this.getAttribute('data-comment-user-id'), 10) ===
+ currentUserID
+ );
})
.addClass('by-viewer');
},
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/comment/js/comment-new-indicator.es6.js b/core/modules/comment/js/comment-new-indicator.es6.js
index 791853e..9ae8246 100644
--- a/core/modules/comment/js/comment-new-indicator.es6.js
+++ b/core/modules/comment/js/comment-new-indicator.es6.js
@@ -6,7 +6,7 @@
* installed.
*/
-(function ($, Drupal, window) {
+(function($, Drupal, window) {
/**
* Processes the markup for "new comment" indicators.
*
@@ -20,7 +20,10 @@
$placeholders.each((index, placeholder) => {
$placeholder = $(placeholder);
- const timestamp = parseInt($placeholder.attr('data-comment-timestamp'), 10);
+ const timestamp = parseInt(
+ $placeholder.attr('data-comment-timestamp'),
+ 10,
+ );
const $node = $placeholder.closest('[data-history-node-id]');
const nodeID = $node.attr('data-history-node-id');
const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
@@ -42,7 +45,10 @@
// If the URL points to the first new comment, then scroll to that
// comment.
if (window.location.hash === '#new') {
- window.scrollTo(0, $comment.offset().top - Drupal.displace.offsets.top);
+ window.scrollTo(
+ 0,
+ $comment.offset().top - Drupal.displace.offsets.top,
+ );
}
}
}
@@ -66,10 +72,15 @@
const $placeholders = $(context)
.find('[data-comment-timestamp]')
.once('history')
- .filter(function () {
+ .filter(function() {
const $placeholder = $(this);
- const commentTimestamp = parseInt($placeholder.attr('data-comment-timestamp'), 10);
- const nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
+ const commentTimestamp = parseInt(
+ $placeholder.attr('data-comment-timestamp'),
+ 10,
+ );
+ const nodeID = $placeholder
+ .closest('[data-history-node-id]')
+ .attr('data-history-node-id');
if (Drupal.history.needsServerCheck(nodeID, commentTimestamp)) {
nodeIDs.push(nodeID);
return true;
@@ -88,4 +99,4 @@
});
},
};
-}(jQuery, Drupal, window));
+})(jQuery, Drupal, window);
diff --git a/core/modules/comment/js/node-new-comments-link.es6.js b/core/modules/comment/js/node-new-comments-link.es6.js
index af95974..d3d0a07 100644
--- a/core/modules/comment/js/node-new-comments-link.es6.js
+++ b/core/modules/comment/js/node-new-comments-link.es6.js
@@ -6,7 +6,7 @@
* installed.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Hides a "new comment" element.
*
@@ -17,15 +17,17 @@
* The placeholder element passed in as a parameter.
*/
function hide($placeholder) {
- return $placeholder
- // Find the parent <li>.
- .closest('.comment-new-comments')
- // Find the preceding <li>, if any, and give it the 'last' class.
- .prev()
- .addClass('last')
- // Go back to the parent <li> and hide it.
- .end()
- .hide();
+ return (
+ $placeholder
+ // Find the parent <li>.
+ .closest('.comment-new-comments')
+ // Find the preceding <li>, if any, and give it the 'last' class.
+ .prev()
+ .addClass('last')
+ // Go back to the parent <li> and hide it.
+ .end()
+ .hide()
+ );
}
/**
@@ -48,15 +50,17 @@
* The placeholder element passed in as a parameter.
*/
function show($placeholder) {
- return $placeholder
- // Find the parent <li>.
- .closest('.comment-new-comments')
- // Find the preceding <li>, if any, and remove its 'last' class, if any.
- .prev()
- .removeClass('last')
- // Go back to the parent <li> and show it.
- .end()
- .show();
+ return (
+ $placeholder
+ // Find the parent <li>.
+ .closest('.comment-new-comments')
+ // Find the preceding <li>, if any, and remove its 'last' class, if any.
+ .prev()
+ .removeClass('last')
+ // Go back to the parent <li> and show it.
+ .end()
+ .show()
+ );
}
/**
@@ -72,9 +76,14 @@
let $placeholder;
$placeholders.each((index, placeholder) => {
$placeholder = $(placeholder);
- const timestamp = parseInt($placeholder.attr('data-history-node-last-comment-timestamp'), 10);
+ const timestamp = parseInt(
+ $placeholder.attr('data-history-node-last-comment-timestamp'),
+ 10,
+ );
fieldName = $placeholder.attr('data-history-node-field-name');
- const nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
+ const nodeID = $placeholder
+ .closest('[data-history-node-id]')
+ .attr('data-history-node-id');
const lastViewTimestamp = Drupal.history.getLastRead(nodeID);
// Queue this placeholder's "X new comments" link to be downloaded from
@@ -104,11 +113,17 @@
* Data about new comment links indexed by nodeID.
*/
function render(results) {
- Object.keys(results || {}).forEach((nodeID) => {
+ Object.keys(results || {}).forEach(nodeID => {
if ($placeholdersToUpdate.hasOwnProperty(nodeID)) {
$placeholdersToUpdate[nodeID]
.attr('href', results[nodeID].first_new_comment_link)
- .text(Drupal.formatPlural(results[nodeID].new_comment_count, '1 new comment', '@count new comments'))
+ .text(
+ Drupal.formatPlural(
+ results[nodeID].new_comment_count,
+ '1 new comment',
+ '@count new comments',
+ ),
+ )
.removeClass('hidden');
show($placeholdersToUpdate[nodeID]);
}
@@ -117,8 +132,7 @@
if (drupalSettings.comment && drupalSettings.comment.newCommentsLinks) {
render(drupalSettings.comment.newCommentsLinks.node[fieldName]);
- }
- else {
+ } else {
$.ajax({
url: Drupal.url('comments/render_new_comments_node_links'),
type: 'POST',
@@ -146,10 +160,15 @@
const $placeholders = $(context)
.find('[data-history-node-last-comment-timestamp]')
.once('history')
- .filter(function () {
+ .filter(function() {
const $placeholder = $(this);
- const lastCommentTimestamp = parseInt($placeholder.attr('data-history-node-last-comment-timestamp'), 10);
- const nodeID = $placeholder.closest('[data-history-node-id]').attr('data-history-node-id');
+ const lastCommentTimestamp = parseInt(
+ $placeholder.attr('data-history-node-last-comment-timestamp'),
+ 10,
+ );
+ const nodeID = $placeholder
+ .closest('[data-history-node-id]')
+ .attr('data-history-node-id');
if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) {
nodeIDs.push(nodeID);
// Hide this placeholder link until it is certain we'll need it.
@@ -173,4 +192,4 @@
});
},
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/content_translation/content_translation.admin.es6.js b/core/modules/content_translation/content_translation.admin.es6.js
index 53ace08..cf4b208 100644
--- a/core/modules/content_translation/content_translation.admin.es6.js
+++ b/core/modules/content_translation/content_translation.admin.es6.js
@@ -3,7 +3,7 @@
* Content Translation admin behaviors.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Forces applicable options to be checked as translatable.
*
@@ -19,8 +19,12 @@
let $fields;
function fieldsChangeHandler($fields, dependentColumns) {
- return function (e) {
- Drupal.behaviors.contentTranslationDependentOptions.check($fields, dependentColumns, $(e.target));
+ return function(e) {
+ Drupal.behaviors.contentTranslationDependentOptions.check(
+ $fields,
+ dependentColumns,
+ $(e.target),
+ );
};
}
@@ -28,12 +32,15 @@
// that name and copy over the input values that require all columns to be
// translatable.
if (options && options.dependent_selectors) {
- Object.keys(options.dependent_selectors).forEach((field) => {
+ Object.keys(options.dependent_selectors).forEach(field => {
$fields = $context.find(`input[name^="${field}"]`);
const dependentColumns = options.dependent_selectors[field];
$fields.on('change', fieldsChangeHandler($fields, dependentColumns));
- Drupal.behaviors.contentTranslationDependentOptions.check($fields, dependentColumns);
+ Drupal.behaviors.contentTranslationDependentOptions.check(
+ $fields,
+ dependentColumns,
+ );
});
}
},
@@ -47,7 +54,7 @@
// A field that has many different translatable parts can also define one
// or more columns that require all columns to be translatable.
- Object.keys(dependentColumns || {}).forEach((index) => {
+ Object.keys(dependentColumns || {}).forEach(index => {
column = dependentColumns[index];
if (!$changed) {
@@ -55,10 +62,11 @@
}
if ($element.is(`input[value="${column}"]:checked`)) {
- $fields.prop('checked', true)
- .not($element).prop('disabled', true);
- }
- else {
+ $fields
+ .prop('checked', true)
+ .not($element)
+ .prop('disabled', true);
+ } else {
$fields.prop('disabled', false);
}
});
@@ -77,50 +85,56 @@
attach(context) {
// Initially hide all field rows for non translatable bundles and all
// column rows for non translatable fields.
- $(context).find('table .bundle-settings .translatable :input').once('translation-entity-admin-hide').each(function () {
- const $input = $(this);
- const $bundleSettings = $input.closest('.bundle-settings');
- if (!$input.is(':checked')) {
- $bundleSettings.nextUntil('.bundle-settings').hide();
- }
- else {
- $bundleSettings
- .nextUntil('.bundle-settings', '.field-settings')
- .find('.translatable :input:not(:checked)')
- .closest('.field-settings')
- .nextUntil(':not(.column-settings)')
- .hide();
- }
- });
+ $(context)
+ .find('table .bundle-settings .translatable :input')
+ .once('translation-entity-admin-hide')
+ .each(function() {
+ const $input = $(this);
+ const $bundleSettings = $input.closest('.bundle-settings');
+ if (!$input.is(':checked')) {
+ $bundleSettings.nextUntil('.bundle-settings').hide();
+ } else {
+ $bundleSettings
+ .nextUntil('.bundle-settings', '.field-settings')
+ .find('.translatable :input:not(:checked)')
+ .closest('.field-settings')
+ .nextUntil(':not(.column-settings)')
+ .hide();
+ }
+ });
// When a bundle is made translatable all of its fields should inherit
// this setting. Instead when it is made non translatable its fields are
// hidden, since their translatability no longer matters.
- $('body').once('translation-entity-admin-bind').on('click', 'table .bundle-settings .translatable :input', (e) => {
- const $target = $(e.target);
- const $bundleSettings = $target.closest('.bundle-settings');
- const $settings = $bundleSettings.nextUntil('.bundle-settings');
- const $fieldSettings = $settings.filter('.field-settings');
- if ($target.is(':checked')) {
- $bundleSettings.find('.operations :input[name$="[language_alterable]"]').prop('checked', true);
- $fieldSettings.find('.translatable :input').prop('checked', true);
- $settings.show();
- }
- else {
- $settings.hide();
- }
- })
- .on('click', 'table .field-settings .translatable :input', (e) => {
+ $('body')
+ .once('translation-entity-admin-bind')
+ .on('click', 'table .bundle-settings .translatable :input', e => {
+ const $target = $(e.target);
+ const $bundleSettings = $target.closest('.bundle-settings');
+ const $settings = $bundleSettings.nextUntil('.bundle-settings');
+ const $fieldSettings = $settings.filter('.field-settings');
+ if ($target.is(':checked')) {
+ $bundleSettings
+ .find('.operations :input[name$="[language_alterable]"]')
+ .prop('checked', true);
+ $fieldSettings.find('.translatable :input').prop('checked', true);
+ $settings.show();
+ } else {
+ $settings.hide();
+ }
+ })
+ .on('click', 'table .field-settings .translatable :input', e => {
const $target = $(e.target);
const $fieldSettings = $target.closest('.field-settings');
- const $columnSettings = $fieldSettings.nextUntil('.field-settings, .bundle-settings');
+ const $columnSettings = $fieldSettings.nextUntil(
+ '.field-settings, .bundle-settings',
+ );
if ($target.is(':checked')) {
$columnSettings.show();
- }
- else {
+ } else {
$columnSettings.hide();
}
});
},
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/contextual/js/contextual.es6.js b/core/modules/contextual/js/contextual.es6.js
index d3e5973..46a5708 100644
--- a/core/modules/contextual/js/contextual.es6.js
+++ b/core/modules/contextual/js/contextual.es6.js
@@ -3,7 +3,7 @@
* Attaches behaviors for the Contextual module.
*/
-(function ($, Drupal, drupalSettings, _, Backbone, JSON, storage) {
+(function($, Drupal, drupalSettings, _, Backbone, JSON, storage) {
const options = $.extend(
drupalSettings.contextual,
// Merge strings on top of drupalSettings so that they are not mutable.
@@ -17,15 +17,19 @@
// Clear the cached contextual links whenever the current user's set of
// permissions changes.
- const cachedPermissionsHash = storage.getItem('Drupal.contextual.permissionsHash');
+ const cachedPermissionsHash = storage.getItem(
+ 'Drupal.contextual.permissionsHash',
+ );
const permissionsHash = drupalSettings.user.permissionsHash;
if (cachedPermissionsHash !== permissionsHash) {
if (typeof permissionsHash === 'string') {
- _.chain(storage).keys().each((key) => {
- if (key.substring(0, 18) === 'Drupal.contextual.') {
- storage.removeItem(key);
- }
- });
+ _.chain(storage)
+ .keys()
+ .each(key => {
+ if (key.substring(0, 18) === 'Drupal.contextual.') {
+ storage.removeItem(key);
+ }
+ });
}
storage.setItem('Drupal.contextual.permissionsHash', permissionsHash);
}
@@ -42,7 +46,8 @@
function adjustIfNestedAndOverlapping($contextual) {
const $contextuals = $contextual
// @todo confirm that .closest() is not sufficient
- .parents('.contextual-region').eq(-1)
+ .parents('.contextual-region')
+ .eq(-1)
.find('.contextual');
// Early-return when there's no nesting.
@@ -93,16 +98,22 @@
.prepend(Drupal.theme('contextualTrigger'));
// Set the destination parameter on each of the contextual links.
- const destination = `destination=${Drupal.encodePath(drupalSettings.path.currentPath)}`;
- $contextual.find('.contextual-links a').each(function () {
+ const destination = `destination=${Drupal.encodePath(
+ drupalSettings.path.currentPath,
+ )}`;
+ $contextual.find('.contextual-links a').each(function() {
const url = this.getAttribute('href');
- const glue = (url.indexOf('?') === -1) ? '?' : '&';
+ const glue = url.indexOf('?') === -1 ? '?' : '&';
this.setAttribute('href', url + glue + destination);
});
// Create a model and the appropriate views.
const model = new contextual.StateModel({
- title: $region.find('h2').eq(0).text().trim(),
+ title: $region
+ .find('h2')
+ .eq(0)
+ .text()
+ .trim(),
});
const viewOptions = $.extend({ el: $contextual, model }, options);
contextual.views.push({
@@ -147,19 +158,21 @@
const $context = $(context);
// Find all contextual links placeholders, if any.
- let $placeholders = $context.find('[data-contextual-id]').once('contextual-render');
+ let $placeholders = $context
+ .find('[data-contextual-id]')
+ .once('contextual-render');
if ($placeholders.length === 0) {
return;
}
// Collect the IDs for all contextual links placeholders.
const ids = [];
- $placeholders.each(function () {
+ $placeholders.each(function() {
ids.push($(this).attr('data-contextual-id'));
});
// Update all contextual links placeholders whose HTML is cached.
- const uncachedIDs = _.filter(ids, (contextualID) => {
+ const uncachedIDs = _.filter(ids, contextualID => {
const html = storage.getItem(`Drupal.contextual.${contextualID}`);
if (html && html.length) {
// Initialize after the current execution cycle, to make the AJAX
@@ -168,7 +181,10 @@
// the chance to set up an event listener on the Backbone collection
// Drupal.contextual.collection.
window.setTimeout(() => {
- initContextual($context.find(`[data-contextual-id="${contextualID}"]`), html);
+ initContextual(
+ $context.find(`[data-contextual-id="${contextualID}"]`),
+ html,
+ );
});
return false;
}
@@ -196,7 +212,9 @@
// possible for multiple identical placeholders exist on the
// page (probably because the same content appears more than
// once).
- $placeholders = $context.find(`[data-contextual-id="${contextualID}"]`);
+ $placeholders = $context.find(
+ `[data-contextual-id="${contextualID}"]`,
+ );
// Initialize the contextual links.
for (let i = 0; i < $placeholders.length; i++) {
@@ -216,7 +234,6 @@
* @namespace
*/
Drupal.contextual = {
-
/**
* The {@link Drupal.contextual.View} instances associated with each list
* element of contextual links.
@@ -239,7 +256,9 @@
*
* @type {Backbone.Collection}
*/
- Drupal.contextual.collection = new Backbone.Collection([], { model: Drupal.contextual.StateModel });
+ Drupal.contextual.collection = new Backbone.Collection([], {
+ model: Drupal.contextual.StateModel,
+ });
/**
* A trigger is an interactive element often bound to a click handler.
@@ -247,7 +266,7 @@
* @return {string}
* A string representing a DOM fragment.
*/
- Drupal.theme.contextualTrigger = function () {
+ Drupal.theme.contextualTrigger = function() {
return '<button class="trigger visually-hidden focusable" type="button"></button>';
};
@@ -264,4 +283,12 @@
$(document).on('drupalContextualLinkAdded', (event, data) => {
Drupal.ajax.bindAjaxLinks(data.$el[0]);
});
-}(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage));
+})(
+ jQuery,
+ Drupal,
+ drupalSettings,
+ _,
+ Backbone,
+ window.JSON,
+ window.sessionStorage,
+);
diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js
index 7e6d000..049233b 100644
--- a/core/modules/contextual/js/contextual.js
+++ b/core/modules/contextual/js/contextual.js
@@ -139,7 +139,9 @@
regionViews: []
};
- Drupal.contextual.collection = new Backbone.Collection([], { model: Drupal.contextual.StateModel });
+ Drupal.contextual.collection = new Backbone.Collection([], {
+ model: Drupal.contextual.StateModel
+ });
Drupal.theme.contextualTrigger = function () {
return '<button class="trigger visually-hidden focusable" type="button"></button>';
diff --git a/core/modules/contextual/js/contextual.toolbar.es6.js b/core/modules/contextual/js/contextual.toolbar.es6.js
index 9538288..953f764 100644
--- a/core/modules/contextual/js/contextual.toolbar.es6.js
+++ b/core/modules/contextual/js/contextual.toolbar.es6.js
@@ -3,10 +3,14 @@
* Attaches behaviors for the Contextual module's edit toolbar tab.
*/
-(function ($, Drupal, Backbone) {
+(function($, Drupal, Backbone) {
const strings = {
- tabbingReleased: Drupal.t('Tabbing is no longer constrained by the Contextual module.'),
- tabbingConstrained: Drupal.t('Tabbing is constrained to a set of @contextualsCount and the edit mode toggle.'),
+ tabbingReleased: Drupal.t(
+ 'Tabbing is no longer constrained by the Contextual module.',
+ ),
+ tabbingConstrained: Drupal.t(
+ 'Tabbing is constrained to a set of @contextualsCount and the edit mode toggle.',
+ ),
pressEsc: Drupal.t('Press the esc key to exit.'),
};
@@ -22,14 +26,19 @@
}
const contextualToolbar = Drupal.contextualToolbar;
- contextualToolbar.model = new contextualToolbar.StateModel({
- // Checks whether localStorage indicates we should start in edit mode
- // rather than view mode.
- // @see Drupal.contextualToolbar.VisualView.persist
- isViewing: localStorage.getItem('Drupal.contextualToolbar.isViewing') !== 'false',
- }, {
- contextualCollection: Drupal.contextual.collection,
- });
+ contextualToolbar.model = new contextualToolbar.StateModel(
+ {
+ // Checks whether localStorage indicates we should start in edit mode
+ // rather than view mode.
+ // @see Drupal.contextualToolbar.VisualView.persist
+ isViewing:
+ localStorage.getItem('Drupal.contextualToolbar.isViewing') !==
+ 'false',
+ },
+ {
+ contextualCollection: Drupal.contextual.collection,
+ },
+ );
const viewOptions = {
el: $('.toolbar .toolbar-bar .contextual-toolbar-tab'),
@@ -62,7 +71,6 @@
* @namespace
*/
Drupal.contextualToolbar = {
-
/**
* The {@link Drupal.contextualToolbar.StateModel} instance.
*
@@ -70,4 +78,4 @@
*/
model: null,
};
-}(jQuery, Drupal, Backbone));
+})(jQuery, Drupal, Backbone);
diff --git a/core/modules/contextual/js/models/StateModel.es6.js b/core/modules/contextual/js/models/StateModel.es6.js
index 2eab4a6..bb142a9 100644
--- a/core/modules/contextual/js/models/StateModel.es6.js
+++ b/core/modules/contextual/js/models/StateModel.es6.js
@@ -3,7 +3,7 @@
* A Backbone Model for the state of a contextual link's trigger, list & region.
*/
-(function (Drupal, Backbone) {
+(function(Drupal, Backbone) {
/**
* Models the state of a contextual link's trigger, list & region.
*
@@ -11,118 +11,117 @@
*
* @augments Backbone.Model
*/
- Drupal.contextual.StateModel = Backbone.Model.extend(/** @lends Drupal.contextual.StateModel# */{
-
- /**
- * @type {object}
- *
- * @prop {string} title
- * @prop {bool} regionIsHovered
- * @prop {bool} hasFocus
- * @prop {bool} isOpen
- * @prop {bool} isLocked
- */
- defaults: /** @lends Drupal.contextual.StateModel# */{
-
+ Drupal.contextual.StateModel = Backbone.Model.extend(
+ /** @lends Drupal.contextual.StateModel# */ {
/**
- * The title of the entity to which these contextual links apply.
+ * @type {object}
*
- * @type {string}
+ * @prop {string} title
+ * @prop {bool} regionIsHovered
+ * @prop {bool} hasFocus
+ * @prop {bool} isOpen
+ * @prop {bool} isLocked
*/
- title: '',
+ defaults: /** @lends Drupal.contextual.StateModel# */ {
+ /**
+ * The title of the entity to which these contextual links apply.
+ *
+ * @type {string}
+ */
+ title: '',
+
+ /**
+ * Represents if the contextual region is being hovered.
+ *
+ * @type {bool}
+ */
+ regionIsHovered: false,
+
+ /**
+ * Represents if the contextual trigger or options have focus.
+ *
+ * @type {bool}
+ */
+ hasFocus: false,
+
+ /**
+ * Represents if the contextual options for an entity are available to
+ * be selected (i.e. whether the list of options is visible).
+ *
+ * @type {bool}
+ */
+ isOpen: false,
+
+ /**
+ * When the model is locked, the trigger remains active.
+ *
+ * @type {bool}
+ */
+ isLocked: false,
+ },
/**
- * Represents if the contextual region is being hovered.
+ * Opens or closes the contextual link.
+ *
+ * If it is opened, then also give focus.
*
- * @type {bool}
+ * @return {Drupal.contextual.StateModel}
+ * The current contextual state model.
*/
- regionIsHovered: false,
+ toggleOpen() {
+ const newIsOpen = !this.get('isOpen');
+ this.set('isOpen', newIsOpen);
+ if (newIsOpen) {
+ this.focus();
+ }
+ return this;
+ },
/**
- * Represents if the contextual trigger or options have focus.
+ * Closes this contextual link.
*
- * @type {bool}
+ * Does not call blur() because we want to allow a contextual link to have
+ * focus, yet be closed for example when hovering.
+ *
+ * @return {Drupal.contextual.StateModel}
+ * The current contextual state model.
*/
- hasFocus: false,
+ close() {
+ this.set('isOpen', false);
+ return this;
+ },
/**
- * Represents if the contextual options for an entity are available to
- * be selected (i.e. whether the list of options is visible).
+ * Gives focus to this contextual link.
+ *
+ * Also closes + removes focus from every other contextual link.
*
- * @type {bool}
+ * @return {Drupal.contextual.StateModel}
+ * The current contextual state model.
*/
- isOpen: false,
+ focus() {
+ this.set('hasFocus', true);
+ const cid = this.cid;
+ this.collection.each(model => {
+ if (model.cid !== cid) {
+ model.close().blur();
+ }
+ });
+ return this;
+ },
/**
- * When the model is locked, the trigger remains active.
+ * Removes focus from this contextual link, unless it is open.
*
- * @type {bool}
+ * @return {Drupal.contextual.StateModel}
+ * The current contextual state model.
*/
- isLocked: false,
- },
-
- /**
- * Opens or closes the contextual link.
- *
- * If it is opened, then also give focus.
- *
- * @return {Drupal.contextual.StateModel}
- * The current contextual state model.
- */
- toggleOpen() {
- const newIsOpen = !this.get('isOpen');
- this.set('isOpen', newIsOpen);
- if (newIsOpen) {
- this.focus();
- }
- return this;
- },
-
- /**
- * Closes this contextual link.
- *
- * Does not call blur() because we want to allow a contextual link to have
- * focus, yet be closed for example when hovering.
- *
- * @return {Drupal.contextual.StateModel}
- * The current contextual state model.
- */
- close() {
- this.set('isOpen', false);
- return this;
- },
-
- /**
- * Gives focus to this contextual link.
- *
- * Also closes + removes focus from every other contextual link.
- *
- * @return {Drupal.contextual.StateModel}
- * The current contextual state model.
- */
- focus() {
- this.set('hasFocus', true);
- const cid = this.cid;
- this.collection.each((model) => {
- if (model.cid !== cid) {
- model.close().blur();
+ blur() {
+ if (!this.get('isOpen')) {
+ this.set('hasFocus', false);
}
- });
- return this;
- },
-
- /**
- * Removes focus from this contextual link, unless it is open.
- *
- * @return {Drupal.contextual.StateModel}
- * The current contextual state model.
- */
- blur() {
- if (!this.get('isOpen')) {
- this.set('hasFocus', false);
- }
- return this;
+ return this;
+ },
},
-
- });
-}(Drupal, Backbone));
+ );
+})(Drupal, Backbone);
diff --git a/core/modules/contextual/js/toolbar/models/StateModel.es6.js b/core/modules/contextual/js/toolbar/models/StateModel.es6.js
index 0a1b161..7378153 100644
--- a/core/modules/contextual/js/toolbar/models/StateModel.es6.js
+++ b/core/modules/contextual/js/toolbar/models/StateModel.es6.js
@@ -3,113 +3,120 @@
* A Backbone Model for the state of Contextual module's edit toolbar tab.
*/
-(function (Drupal, Backbone) {
- Drupal.contextualToolbar.StateModel = Backbone.Model.extend(/** @lends Drupal.contextualToolbar.StateModel# */{
-
- /**
- * @type {object}
- *
- * @prop {bool} isViewing
- * @prop {bool} isVisible
- * @prop {number} contextualCount
- * @prop {Drupal~TabbingContext} tabbingContext
- */
- defaults: /** @lends Drupal.contextualToolbar.StateModel# */{
-
+(function(Drupal, Backbone) {
+ Drupal.contextualToolbar.StateModel = Backbone.Model.extend(
+ /** @lends Drupal.contextualToolbar.StateModel# */ {
/**
- * Indicates whether the toggle is currently in "view" or "edit" mode.
+ * @type {object}
*
- * @type {bool}
+ * @prop {bool} isViewing
+ * @prop {bool} isVisible
+ * @prop {number} contextualCount
+ * @prop {Drupal~TabbingContext} tabbingContext
*/
- isViewing: true,
+ defaults: /** @lends Drupal.contextualToolbar.StateModel# */ {
+ /**
+ * Indicates whether the toggle is currently in "view" or "edit" mode.
+ *
+ * @type {bool}
+ */
+ isViewing: true,
+
+ /**
+ * Indicates whether the toggle should be visible or hidden. Automatically
+ * calculated, depends on contextualCount.
+ *
+ * @type {bool}
+ */
+ isVisible: false,
+
+ /**
+ * Tracks how many contextual links exist on the page.
+ *
+ * @type {number}
+ */
+ contextualCount: 0,
+
+ /**
+ * A TabbingContext object as returned by {@link Drupal~TabbingManager}:
+ * the set of tabbable elements when edit mode is enabled.
+ *
+ * @type {?Drupal~TabbingContext}
+ */
+ tabbingContext: null,
+ },
/**
- * Indicates whether the toggle should be visible or hidden. Automatically
- * calculated, depends on contextualCount.
+ * Models the state of the edit mode toggle.
+ *
+ * @constructs
*
- * @type {bool}
+ * @augments Backbone.Model
+ *
+ * @param {object} attrs
+ * Attributes for the backbone model.
+ * @param {object} options
+ * An object with the following option:
+ * @param {Backbone.collection} options.contextualCollection
+ * The collection of {@link Drupal.contextual.StateModel} models that
+ * represent the contextual links on the page.
*/
- isVisible: false,
+ initialize(attrs, options) {
+ // Respond to new/removed contextual links.
+ this.listenTo(
+ options.contextualCollection,
+ 'reset remove add',
+ this.countContextualLinks,
+ );
+ this.listenTo(
+ options.contextualCollection,
+ 'add',
+ this.lockNewContextualLinks,
+ );
+
+ // Automatically determine visibility.
+ this.listenTo(this, 'change:contextualCount', this.updateVisibility);
+
+ // Whenever edit mode is toggled, lock all contextual links.
+ this.listenTo(this, 'change:isViewing', (model, isViewing) => {
+ options.contextualCollection.each(contextualModel => {
+ contextualModel.set('isLocked', !isViewing);
+ });
+ });
+ },
/**
- * Tracks how many contextual links exist on the page.
+ * Tracks the number of contextual link models in the collection.
*
- * @type {number}
+ * @param {Drupal.contextual.StateModel} contextualModel
+ * The contextual links model that was added or removed.
+ * @param {Backbone.Collection} contextualCollection
+ * The collection of contextual link models.
*/
- contextualCount: 0,
+ countContextualLinks(contextualModel, contextualCollection) {
+ this.set('contextualCount', contextualCollection.length);
+ },
/**
- * A TabbingContext object as returned by {@link Drupal~TabbingManager}:
- * the set of tabbable elements when edit mode is enabled.
+ * Lock newly added contextual links if edit mode is enabled.
*
- * @type {?Drupal~TabbingContext}
+ * @param {Drupal.contextual.StateModel} contextualModel
+ * The contextual links model that was added.
+ * @param {Backbone.Collection} [contextualCollection]
+ * The collection of contextual link models.
*/
- tabbingContext: null,
- },
-
- /**
- * Models the state of the edit mode toggle.
- *
- * @constructs
- *
- * @augments Backbone.Model
- *
- * @param {object} attrs
- * Attributes for the backbone model.
- * @param {object} options
- * An object with the following option:
- * @param {Backbone.collection} options.contextualCollection
- * The collection of {@link Drupal.contextual.StateModel} models that
- * represent the contextual links on the page.
- */
- initialize(attrs, options) {
- // Respond to new/removed contextual links.
- this.listenTo(options.contextualCollection, 'reset remove add', this.countContextualLinks);
- this.listenTo(options.contextualCollection, 'add', this.lockNewContextualLinks);
+ lockNewContextualLinks(contextualModel, contextualCollection) {
+ if (!this.get('isViewing')) {
+ contextualModel.set('isLocked', true);
+ }
+ },
- // Automatically determine visibility.
- this.listenTo(this, 'change:contextualCount', this.updateVisibility);
-
- // Whenever edit mode is toggled, lock all contextual links.
- this.listenTo(this, 'change:isViewing', (model, isViewing) => {
- options.contextualCollection.each((contextualModel) => {
- contextualModel.set('isLocked', !isViewing);
- });
- });
- },
-
- /**
- * Tracks the number of contextual link models in the collection.
- *
- * @param {Drupal.contextual.StateModel} contextualModel
- * The contextual links model that was added or removed.
- * @param {Backbone.Collection} contextualCollection
- * The collection of contextual link models.
- */
- countContextualLinks(contextualModel, contextualCollection) {
- this.set('contextualCount', contextualCollection.length);
- },
-
- /**
- * Lock newly added contextual links if edit mode is enabled.
- *
- * @param {Drupal.contextual.StateModel} contextualModel
- * The contextual links model that was added.
- * @param {Backbone.Collection} [contextualCollection]
- * The collection of contextual link models.
- */
- lockNewContextualLinks(contextualModel, contextualCollection) {
- if (!this.get('isViewing')) {
- contextualModel.set('isLocked', true);
- }
- },
-
- /**
- * Automatically updates visibility of the view/edit mode toggle.
- */
- updateVisibility() {
- this.set('isVisible', this.get('contextualCount') > 0);
+ /**
+ * Automatically updates visibility of the view/edit mode toggle.
+ */
+ updateVisibility() {
+ this.set('isVisible', this.get('contextualCount') > 0);
+ },
},
-
- });
-}(Drupal, Backbone));
+ );
+})(Drupal, Backbone);
diff --git a/core/modules/contextual/js/toolbar/views/AuralView.es6.js b/core/modules/contextual/js/toolbar/views/AuralView.es6.js
index 757c886..3d34335 100644
--- a/core/modules/contextual/js/toolbar/views/AuralView.es6.js
+++ b/core/modules/contextual/js/toolbar/views/AuralView.es6.js
@@ -3,102 +3,116 @@
* A Backbone View that provides the aural view of the edit mode toggle.
*/
-(function ($, Drupal, Backbone, _) {
- Drupal.contextualToolbar.AuralView = Backbone.View.extend(/** @lends Drupal.contextualToolbar.AuralView# */{
+(function($, Drupal, Backbone, _) {
+ Drupal.contextualToolbar.AuralView = Backbone.View.extend(
+ /** @lends Drupal.contextualToolbar.AuralView# */ {
+ /**
+ * Tracks whether the tabbing constraint announcement has been read once.
+ *
+ * @type {bool}
+ */
+ announcedOnce: false,
- /**
- * Tracks whether the tabbing constraint announcement has been read once.
- *
- * @type {bool}
- */
- announcedOnce: false,
+ /**
+ * Renders the aural view of the edit mode toggle (screen reader support).
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ *
+ * @param {object} options
+ * Options for the view.
+ */
+ initialize(options) {
+ this.options = options;
- /**
- * Renders the aural view of the edit mode toggle (screen reader support).
- *
- * @constructs
- *
- * @augments Backbone.View
- *
- * @param {object} options
- * Options for the view.
- */
- initialize(options) {
- this.options = options;
+ this.listenTo(this.model, 'change', this.render);
+ this.listenTo(this.model, 'change:isViewing', this.manageTabbing);
- this.listenTo(this.model, 'change', this.render);
- this.listenTo(this.model, 'change:isViewing', this.manageTabbing);
+ $(document).on('keyup', _.bind(this.onKeypress, this));
+ this.manageTabbing();
+ },
- $(document).on('keyup', _.bind(this.onKeypress, this));
- this.manageTabbing();
- },
-
- /**
- * @inheritdoc
- *
- * @return {Drupal.contextualToolbar.AuralView}
- * The current contextual toolbar aural view.
- */
- render() {
- // Render the state.
- this.$el.find('button').attr('aria-pressed', !this.model.get('isViewing'));
+ /**
+ * @inheritdoc
+ *
+ * @return {Drupal.contextualToolbar.AuralView}
+ * The current contextual toolbar aural view.
+ */
+ render() {
+ // Render the state.
+ this.$el
+ .find('button')
+ .attr('aria-pressed', !this.model.get('isViewing'));
- return this;
- },
+ return this;
+ },
- /**
- * Limits tabbing to the contextual links and edit mode toolbar tab.
- */
- manageTabbing() {
- let tabbingContext = this.model.get('tabbingContext');
- // Always release an existing tabbing context.
- if (tabbingContext) {
- // Only announce release when the context was active.
- if (tabbingContext.active) {
- Drupal.announce(this.options.strings.tabbingReleased);
+ /**
+ * Limits tabbing to the contextual links and edit mode toolbar tab.
+ */
+ manageTabbing() {
+ let tabbingContext = this.model.get('tabbingContext');
+ // Always release an existing tabbing context.
+ if (tabbingContext) {
+ // Only announce release when the context was active.
+ if (tabbingContext.active) {
+ Drupal.announce(this.options.strings.tabbingReleased);
+ }
+ tabbingContext.release();
}
- tabbingContext.release();
- }
- // Create a new tabbing context when edit mode is enabled.
- if (!this.model.get('isViewing')) {
- tabbingContext = Drupal.tabbingManager.constrain($('.contextual-toolbar-tab, .contextual'));
- this.model.set('tabbingContext', tabbingContext);
- this.announceTabbingConstraint();
- this.announcedOnce = true;
- }
- },
+ // Create a new tabbing context when edit mode is enabled.
+ if (!this.model.get('isViewing')) {
+ tabbingContext = Drupal.tabbingManager.constrain(
+ $('.contextual-toolbar-tab, .contextual'),
+ );
+ this.model.set('tabbingContext', tabbingContext);
+ this.announceTabbingConstraint();
+ this.announcedOnce = true;
+ }
+ },
- /**
- * Announces the current tabbing constraint.
- */
- announceTabbingConstraint() {
- const strings = this.options.strings;
- Drupal.announce(Drupal.formatString(strings.tabbingConstrained, {
- '@contextualsCount': Drupal.formatPlural(Drupal.contextual.collection.length, '@count contextual link', '@count contextual links'),
- }));
- Drupal.announce(strings.pressEsc);
- },
+ /**
+ * Announces the current tabbing constraint.
+ */
+ announceTabbingConstraint() {
+ const strings = this.options.strings;
+ Drupal.announce(
+ Drupal.formatString(strings.tabbingConstrained, {
+ '@contextualsCount': Drupal.formatPlural(
+ Drupal.contextual.collection.length,
+ '@count contextual link',
+ '@count contextual links',
+ ),
+ }),
+ );
+ Drupal.announce(strings.pressEsc);
+ },
- /**
- * Responds to esc and tab key press events.
- *
- * @param {jQuery.Event} event
- * The keypress event.
- */
- onKeypress(event) {
- // The first tab key press is tracked so that an annoucement about tabbing
- // constraints can be raised if edit mode is enabled when the page is
- // loaded.
- if (!this.announcedOnce && event.keyCode === 9 && !this.model.get('isViewing')) {
- this.announceTabbingConstraint();
- // Set announce to true so that this conditional block won't run again.
- this.announcedOnce = true;
- }
- // Respond to the ESC key. Exit out of edit mode.
- if (event.keyCode === 27) {
- this.model.set('isViewing', true);
- }
+ /**
+ * Responds to esc and tab key press events.
+ *
+ * @param {jQuery.Event} event
+ * The keypress event.
+ */
+ onKeypress(event) {
+ // The first tab key press is tracked so that an annoucement about tabbing
+ // constraints can be raised if edit mode is enabled when the page is
+ // loaded.
+ if (
+ !this.announcedOnce &&
+ event.keyCode === 9 &&
+ !this.model.get('isViewing')
+ ) {
+ this.announceTabbingConstraint();
+ // Set announce to true so that this conditional block won't run again.
+ this.announcedOnce = true;
+ }
+ // Respond to the ESC key. Exit out of edit mode.
+ if (event.keyCode === 27) {
+ this.model.set('isViewing', true);
+ }
+ },
},
-
- });
-}(jQuery, Drupal, Backbone, _));
+ );
+})(jQuery, Drupal, Backbone, _);
diff --git a/core/modules/contextual/js/toolbar/views/VisualView.es6.js b/core/modules/contextual/js/toolbar/views/VisualView.es6.js
index 56bae27..d168d54 100644
--- a/core/modules/contextual/js/toolbar/views/VisualView.es6.js
+++ b/core/modules/contextual/js/toolbar/views/VisualView.es6.js
@@ -3,78 +3,79 @@
* A Backbone View that provides the visual view of the edit mode toggle.
*/
-(function (Drupal, Backbone) {
- Drupal.contextualToolbar.VisualView = Backbone.View.extend(/** @lends Drupal.contextualToolbar.VisualView# */{
+(function(Drupal, Backbone) {
+ Drupal.contextualToolbar.VisualView = Backbone.View.extend(
+ /** @lends Drupal.contextualToolbar.VisualView# */ {
+ /**
+ * Events for the Backbone view.
+ *
+ * @return {object}
+ * A mapping of events to be used in the view.
+ */
+ events() {
+ // Prevents delay and simulated mouse events.
+ const touchEndToClick = function(event) {
+ event.preventDefault();
+ event.target.click();
+ };
- /**
- * Events for the Backbone view.
- *
- * @return {object}
- * A mapping of events to be used in the view.
- */
- events() {
- // Prevents delay and simulated mouse events.
- const touchEndToClick = function (event) {
- event.preventDefault();
- event.target.click();
- };
+ return {
+ click() {
+ this.model.set('isViewing', !this.model.get('isViewing'));
+ },
+ touchend: touchEndToClick,
+ };
+ },
- return {
- click() {
- this.model.set('isViewing', !this.model.get('isViewing'));
- },
- touchend: touchEndToClick,
- };
- },
+ /**
+ * Renders the visual view of the edit mode toggle.
+ *
+ * Listens to mouse & touch and handles edit mode toggle interactions.
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ this.listenTo(this.model, 'change', this.render);
+ this.listenTo(this.model, 'change:isViewing', this.persist);
+ },
- /**
- * Renders the visual view of the edit mode toggle.
- *
- * Listens to mouse & touch and handles edit mode toggle interactions.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- this.listenTo(this.model, 'change', this.render);
- this.listenTo(this.model, 'change:isViewing', this.persist);
- },
+ /**
+ * @inheritdoc
+ *
+ * @return {Drupal.contextualToolbar.VisualView}
+ * The current contextual toolbar visual view.
+ */
+ render() {
+ // Render the visibility.
+ this.$el.toggleClass('hidden', !this.model.get('isVisible'));
+ // Render the state.
+ this.$el
+ .find('button')
+ .toggleClass('is-active', !this.model.get('isViewing'));
- /**
- * @inheritdoc
- *
- * @return {Drupal.contextualToolbar.VisualView}
- * The current contextual toolbar visual view.
- */
- render() {
- // Render the visibility.
- this.$el.toggleClass('hidden', !this.model.get('isVisible'));
- // Render the state.
- this.$el.find('button').toggleClass('is-active', !this.model.get('isViewing'));
+ return this;
+ },
- return this;
+ /**
+ * Model change handler; persists the isViewing value to localStorage.
+ *
+ * `isViewing === true` is the default, so only stores in localStorage when
+ * it's not the default value (i.e. false).
+ *
+ * @param {Drupal.contextualToolbar.StateModel} model
+ * A {@link Drupal.contextualToolbar.StateModel} model.
+ * @param {bool} isViewing
+ * The value of the isViewing attribute in the model.
+ */
+ persist(model, isViewing) {
+ if (!isViewing) {
+ localStorage.setItem('Drupal.contextualToolbar.isViewing', 'false');
+ } else {
+ localStorage.removeItem('Drupal.contextualToolbar.isViewing');
+ }
+ },
},
-
- /**
- * Model change handler; persists the isViewing value to localStorage.
- *
- * `isViewing === true` is the default, so only stores in localStorage when
- * it's not the default value (i.e. false).
- *
- * @param {Drupal.contextualToolbar.StateModel} model
- * A {@link Drupal.contextualToolbar.StateModel} model.
- * @param {bool} isViewing
- * The value of the isViewing attribute in the model.
- */
- persist(model, isViewing) {
- if (!isViewing) {
- localStorage.setItem('Drupal.contextualToolbar.isViewing', 'false');
- }
- else {
- localStorage.removeItem('Drupal.contextualToolbar.isViewing');
- }
- },
-
- });
-}(Drupal, Backbone));
+ );
+})(Drupal, Backbone);
diff --git a/core/modules/contextual/js/views/AuralView.es6.js b/core/modules/contextual/js/views/AuralView.es6.js
index 0141b04..2757423 100644
--- a/core/modules/contextual/js/views/AuralView.es6.js
+++ b/core/modules/contextual/js/views/AuralView.es6.js
@@ -3,49 +3,53 @@
* A Backbone View that provides the aural view of a contextual link.
*/
-(function (Drupal, Backbone) {
- Drupal.contextual.AuralView = Backbone.View.extend(/** @lends Drupal.contextual.AuralView# */{
-
- /**
- * Renders the aural view of a contextual link (i.e. screen reader support).
- *
- * @constructs
- *
- * @augments Backbone.View
- *
- * @param {object} options
- * Options for the view.
- */
- initialize(options) {
- this.options = options;
-
- this.listenTo(this.model, 'change', this.render);
-
- // Use aria-role form so that the number of items in the list is spoken.
- this.$el.attr('role', 'form');
-
- // Initial render.
- this.render();
+(function(Drupal, Backbone) {
+ Drupal.contextual.AuralView = Backbone.View.extend(
+ /** @lends Drupal.contextual.AuralView# */ {
+ /**
+ * Renders the aural view of a contextual link (i.e. screen reader support).
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ *
+ * @param {object} options
+ * Options for the view.
+ */
+ initialize(options) {
+ this.options = options;
+
+ this.listenTo(this.model, 'change', this.render);
+
+ // Use aria-role form so that the number of items in the list is spoken.
+ this.$el.attr('role', 'form');
+
+ // Initial render.
+ this.render();
+ },
+
+ /**
+ * @inheritdoc
+ */
+ render() {
+ const isOpen = this.model.get('isOpen');
+
+ // Set the hidden property of the links.
+ this.$el.find('.contextual-links').prop('hidden', !isOpen);
+
+ // Update the view of the trigger.
+ this.$el
+ .find('.trigger')
+ .text(
+ Drupal.t('@action @title configuration options', {
+ '@action': !isOpen
+ ? this.options.strings.open
+ : this.options.strings.close,
+ '@title': this.model.get('title'),
+ }),
+ )
+ .attr('aria-pressed', isOpen);
+ },
},
-
- /**
- * @inheritdoc
- */
- render() {
- const isOpen = this.model.get('isOpen');
-
- // Set the hidden property of the links.
- this.$el.find('.contextual-links')
- .prop('hidden', !isOpen);
-
- // Update the view of the trigger.
- this.$el.find('.trigger')
- .text(Drupal.t('@action @title configuration options', {
- '@action': (!isOpen) ? this.options.strings.open : this.options.strings.close,
- '@title': this.model.get('title'),
- }))
- .attr('aria-pressed', isOpen);
- },
-
- });
-}(Drupal, Backbone));
+ );
+})(Drupal, Backbone);
diff --git a/core/modules/contextual/js/views/KeyboardView.es6.js b/core/modules/contextual/js/views/KeyboardView.es6.js
index 908b249..4c13f08 100644
--- a/core/modules/contextual/js/views/KeyboardView.es6.js
+++ b/core/modules/contextual/js/views/KeyboardView.es6.js
@@ -3,56 +3,56 @@
* A Backbone View that provides keyboard interaction for a contextual link.
*/
-(function (Drupal, Backbone) {
- Drupal.contextual.KeyboardView = Backbone.View.extend(/** @lends Drupal.contextual.KeyboardView# */{
-
- /**
- * @type {object}
- */
- events: {
- 'focus .trigger': 'focus',
- 'focus .contextual-links a': 'focus',
- 'blur .trigger': function () {
- this.model.blur();
- },
- 'blur .contextual-links a': function () {
- // Set up a timeout to allow a user to tab between the trigger and the
- // contextual links without the menu dismissing.
- const that = this;
- this.timer = window.setTimeout(() => {
- that.model.close().blur();
- }, 150);
+(function(Drupal, Backbone) {
+ Drupal.contextual.KeyboardView = Backbone.View.extend(
+ /** @lends Drupal.contextual.KeyboardView# */ {
+ /**
+ * @type {object}
+ */
+ events: {
+ 'focus .trigger': 'focus',
+ 'focus .contextual-links a': 'focus',
+ 'blur .trigger': function() {
+ this.model.blur();
+ },
+ 'blur .contextual-links a': function() {
+ // Set up a timeout to allow a user to tab between the trigger and the
+ // contextual links without the menu dismissing.
+ const that = this;
+ this.timer = window.setTimeout(() => {
+ that.model.close().blur();
+ }, 150);
+ },
},
- },
- /**
- * Provides keyboard interaction for a contextual link.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
/**
- * The timer is used to create a delay before dismissing the contextual
- * links on blur. This is only necessary when keyboard users tab into
- * contextual links without edit mode (i.e. without TabbingManager).
- * That means that if we decide to disable tabbing of contextual links
- * without edit mode, all this timer logic can go away.
+ * Provides keyboard interaction for a contextual link.
+ *
+ * @constructs
*
- * @type {NaN|number}
+ * @augments Backbone.View
*/
- this.timer = NaN;
- },
+ initialize() {
+ /**
+ * The timer is used to create a delay before dismissing the contextual
+ * links on blur. This is only necessary when keyboard users tab into
+ * contextual links without edit mode (i.e. without TabbingManager).
+ * That means that if we decide to disable tabbing of contextual links
+ * without edit mode, all this timer logic can go away.
+ *
+ * @type {NaN|number}
+ */
+ this.timer = NaN;
+ },
- /**
- * Sets focus on the model; Clears the timer that dismisses the links.
- */
- focus() {
- // Clear the timeout that might have been set by blurring a link.
- window.clearTimeout(this.timer);
- this.model.focus();
+ /**
+ * Sets focus on the model; Clears the timer that dismisses the links.
+ */
+ focus() {
+ // Clear the timeout that might have been set by blurring a link.
+ window.clearTimeout(this.timer);
+ this.model.focus();
+ },
},
-
- });
-}(Drupal, Backbone));
+ );
+})(Drupal, Backbone);
diff --git a/core/modules/contextual/js/views/RegionView.es6.js b/core/modules/contextual/js/views/RegionView.es6.js
index c1d3e8f..57048a7 100644
--- a/core/modules/contextual/js/views/RegionView.es6.js
+++ b/core/modules/contextual/js/views/RegionView.es6.js
@@ -3,53 +3,56 @@
* A Backbone View that renders the visual view of a contextual region element.
*/
-(function (Drupal, Backbone, Modernizr) {
- Drupal.contextual.RegionView = Backbone.View.extend(/** @lends Drupal.contextual.RegionView# */{
+(function(Drupal, Backbone, Modernizr) {
+ Drupal.contextual.RegionView = Backbone.View.extend(
+ /** @lends Drupal.contextual.RegionView# */ {
+ /**
+ * Events for the Backbone view.
+ *
+ * @return {object}
+ * A mapping of events to be used in the view.
+ */
+ events() {
+ let mapping = {
+ mouseenter() {
+ this.model.set('regionIsHovered', true);
+ },
+ mouseleave() {
+ this.model
+ .close()
+ .blur()
+ .set('regionIsHovered', false);
+ },
+ };
+ // We don't want mouse hover events on touch.
+ if (Modernizr.touchevents) {
+ mapping = {};
+ }
+ return mapping;
+ },
- /**
- * Events for the Backbone view.
- *
- * @return {object}
- * A mapping of events to be used in the view.
- */
- events() {
- let mapping = {
- mouseenter() {
- this.model.set('regionIsHovered', true);
- },
- mouseleave() {
- this.model.close().blur().set('regionIsHovered', false);
- },
- };
- // We don't want mouse hover events on touch.
- if (Modernizr.touchevents) {
- mapping = {};
- }
- return mapping;
- },
-
- /**
- * Renders the visual view of a contextual region element.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- this.listenTo(this.model, 'change:hasFocus', this.render);
- },
+ /**
+ * Renders the visual view of a contextual region element.
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ this.listenTo(this.model, 'change:hasFocus', this.render);
+ },
- /**
- * @inheritdoc
- *
- * @return {Drupal.contextual.RegionView}
- * The current contextual region view.
- */
- render() {
- this.$el.toggleClass('focus', this.model.get('hasFocus'));
+ /**
+ * @inheritdoc
+ *
+ * @return {Drupal.contextual.RegionView}
+ * The current contextual region view.
+ */
+ render() {
+ this.$el.toggleClass('focus', this.model.get('hasFocus'));
- return this;
+ return this;
+ },
},
-
- });
-}(Drupal, Backbone, Modernizr));
+ );
+})(Drupal, Backbone, Modernizr);
diff --git a/core/modules/contextual/js/views/VisualView.es6.js b/core/modules/contextual/js/views/VisualView.es6.js
index 385fa7d..57f68ca 100644
--- a/core/modules/contextual/js/views/VisualView.es6.js
+++ b/core/modules/contextual/js/views/VisualView.es6.js
@@ -3,80 +3,85 @@
* A Backbone View that provides the visual view of a contextual link.
*/
-(function (Drupal, Backbone, Modernizr) {
- Drupal.contextual.VisualView = Backbone.View.extend(/** @lends Drupal.contextual.VisualView# */{
-
- /**
- * Events for the Backbone view.
- *
- * @return {object}
- * A mapping of events to be used in the view.
- */
- events() {
- // Prevents delay and simulated mouse events.
- const touchEndToClick = function (event) {
- event.preventDefault();
- event.target.click();
- };
- const mapping = {
- 'click .trigger': function () {
- this.model.toggleOpen();
- },
- 'touchend .trigger': touchEndToClick,
- 'click .contextual-links a': function () {
- this.model.close().blur();
- },
- 'touchend .contextual-links a': touchEndToClick,
- };
- // We only want mouse hover events on non-touch.
- if (!Modernizr.touchevents) {
- mapping.mouseenter = function () {
- this.model.focus();
+(function(Drupal, Backbone, Modernizr) {
+ Drupal.contextual.VisualView = Backbone.View.extend(
+ /** @lends Drupal.contextual.VisualView# */ {
+ /**
+ * Events for the Backbone view.
+ *
+ * @return {object}
+ * A mapping of events to be used in the view.
+ */
+ events() {
+ // Prevents delay and simulated mouse events.
+ const touchEndToClick = function(event) {
+ event.preventDefault();
+ event.target.click();
};
- }
- return mapping;
- },
+ const mapping = {
+ 'click .trigger': function() {
+ this.model.toggleOpen();
+ },
+ 'touchend .trigger': touchEndToClick,
+ 'click .contextual-links a': function() {
+ this.model.close().blur();
+ },
+ 'touchend .contextual-links a': touchEndToClick,
+ };
+ // We only want mouse hover events on non-touch.
+ if (!Modernizr.touchevents) {
+ mapping.mouseenter = function() {
+ this.model.focus();
+ };
+ }
+ return mapping;
+ },
- /**
- * Renders the visual view of a contextual link. Listens to mouse & touch.
- *
- * @constructs
- *
- * @augments Backbone.View
- */
- initialize() {
- this.listenTo(this.model, 'change', this.render);
- },
+ /**
+ * Renders the visual view of a contextual link. Listens to mouse & touch.
+ *
+ * @constructs
+ *
+ * @augments Backbone.View
+ */
+ initialize() {
+ this.listenTo(this.model, 'change', this.render);
+ },
- /**
- * @inheritdoc
- *
- * @return {Drupal.contextual.VisualView}
- * The current contextual visual view.
- */
- render() {
- const isOpen = this.model.get('isOpen');
- // The trigger should be visible when:
- // - the mouse hovered over the region,
- // - the trigger is locked,
- // - and for as long as the contextual menu is open.
- const isVisible = this.model.get('isLocked') || this.model.get('regionIsHovered') || isOpen;
+ /**
+ * @inheritdoc
+ *
+ * @return {Drupal.contextual.VisualView}
+ * The current contextual visual view.
+ */
+ render() {
+ const isOpen = this.model.get('isOpen');
+ // The trigger should be visible when:
+ // - the mouse hovered over the region,
+ // - the trigger is locked,
+ // - and for as long as the contextual menu is open.
+ const isVisible =
+ this.model.get('isLocked') ||
+ this.model.get('regionIsHovered') ||
+ isOpen;
- this.$el
- // The open state determines if the links are visible.
- .toggleClass('open', isOpen)
- // Update the visibility of the trigger.
- .find('.trigger').toggleClass('visually-hidden', !isVisible);
+ this.$el
+ // The open state determines if the links are visible.
+ .toggleClass('open', isOpen)
+ // Update the visibility of the trigger.
+ .find('.trigger')
+ .toggleClass('visually-hidden', !isVisible);
- // Nested contextual region handling: hide any nested contextual triggers.
- if ('isOpen' in this.model.changed) {
- this.$el.closest('.contextual-region')
- .find('.contextual .trigger:not(:first)')
- .toggle(!isOpen);
- }
+ // Nested contextual region handling: hide any nested contextual triggers.
+ if ('isOpen' in this.model.changed) {
+ this.$el
+ .closest('.contextual-region')
+ .find('.contextual .trigger:not(:first)')
+ .toggle(!isOpen);
+ }
- return this;
+ return this;
+ },
},
-
- });
-}(Drupal, Backbone, Modernizr));
+ );
+})(Drupal, Backbone, Modernizr);
diff --git a/core/modules/editor/js/editor.admin.es6.js b/core/modules/editor/js/editor.admin.es6.js
index 3b5a7aa..189193f 100644
--- a/core/modules/editor/js/editor.admin.es6.js
+++ b/core/modules/editor/js/editor.admin.es6.js
@@ -7,14 +7,13 @@
* to automatically adjust their settings based on the editor configuration.
*/
-(function ($, _, Drupal, document) {
+(function($, _, Drupal, document) {
/**
* Editor configuration namespace.
*
* @namespace
*/
Drupal.editorConfiguration = {
-
/**
* Must be called by a specific text editor's configuration whenever a
* feature is added by the user.
@@ -99,7 +98,11 @@
* Returns true if the section has empty properties, false otherwise.
*/
function emptyProperties(section) {
- return section.attributes.length === 0 && section.classes.length === 0 && section.styles.length === 0;
+ return (
+ section.attributes.length === 0 &&
+ section.classes.length === 0 &&
+ section.styles.length === 0
+ );
}
/**
@@ -216,7 +219,13 @@
* @return {bool}
* Returns true if found, false otherwise.
*/
- function findPropertyValueOnTag(universe, tag, property, propertyValue, allowing) {
+ function findPropertyValueOnTag(
+ universe,
+ tag,
+ property,
+ propertyValue,
+ allowing,
+ ) {
// If the tag does not exist in the universe, then it definitely can't
// have this specific property value.
if (!_.has(universe, tag)) {
@@ -246,7 +255,7 @@
let atLeastOneFound = false;
const regex = key.replace(/\*/g, '[^ ]*');
- _.each(_.keys(universe[tag]), (key) => {
+ _.each(_.keys(universe[tag]), key => {
if (key.match(regex)) {
atLeastOneFound = true;
if (allowing) {
@@ -272,11 +281,24 @@
* @return {bool}
* Returns true if found, false otherwise.
*/
- function findPropertyValuesOnAllTags(universe, property, propertyValues, allowing) {
+ function findPropertyValuesOnAllTags(
+ universe,
+ property,
+ propertyValues,
+ allowing,
+ ) {
let atLeastOneFound = false;
- _.each(_.keys(universe), (tag) => {
- // eslint-disable-next-line no-use-before-define
- if (findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing)) {
+ _.each(_.keys(universe), tag => {
+ if (
+ // eslint-disable-next-line no-use-before-define
+ findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ propertyValues,
+ allowing,
+ )
+ ) {
atLeastOneFound = true;
}
});
@@ -302,15 +324,34 @@
* @return {bool}
* Returns true if found, false otherwise.
*/
- function findPropertyValuesOnTag(universe, tag, property, propertyValues, allowing) {
+ function findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ propertyValues,
+ allowing,
+ ) {
// Detect the wildcard case.
if (tag === '*') {
- return findPropertyValuesOnAllTags(universe, property, propertyValues, allowing);
+ return findPropertyValuesOnAllTags(
+ universe,
+ property,
+ propertyValues,
+ allowing,
+ );
}
let atLeastOneFound = false;
- _.each(propertyValues, (propertyValue) => {
- if (findPropertyValueOnTag(universe, tag, property, propertyValue, allowing)) {
+ _.each(propertyValues, propertyValue => {
+ if (
+ findPropertyValueOnTag(
+ universe,
+ tag,
+ property,
+ propertyValue,
+ allowing,
+ )
+ ) {
atLeastOneFound = true;
}
});
@@ -328,7 +369,7 @@
*/
function deleteAllTagsFromUniverseIfAllowed(universe) {
let atLeastOneDeleted = false;
- _.each(_.keys(universe), (tag) => {
+ _.each(_.keys(universe), tag => {
// eslint-disable-next-line no-use-before-define
if (deleteFromUniverseIfAllowed(universe, tag)) {
atLeastOneDeleted = true;
@@ -354,7 +395,10 @@
if (tag === '*') {
return deleteAllTagsFromUniverseIfAllowed(universe);
}
- if (_.has(universe, tag) && _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))) {
+ if (
+ _.has(universe, tag) &&
+ _.every(_.omit(universe[tag], 'touchedByAllowedPropertyRule'))
+ ) {
delete universe[tag];
return true;
}
@@ -393,7 +437,10 @@
for (let n = 0; n < filterStatus.rules.length; n++) {
filterRule = filterStatus.rules[n];
// … if there are tags with restricted property values …
- if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.forbidden)) {
+ if (
+ filterRule.restrictedTags.tags.length &&
+ !emptyProperties(filterRule.restrictedTags.forbidden)
+ ) {
// … for all those tags …
for (let j = 0; j < filterRule.restrictedTags.tags.length; j++) {
const tag = filterRule.restrictedTags.tags[j];
@@ -402,7 +449,15 @@
const property = properties[k];
// … and return true if just one of the forbidden property
// values for this tag and property is listed in the universe.
- if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.forbidden[property], false)) {
+ if (
+ findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ filterRule.restrictedTags.forbidden[property],
+ false,
+ )
+ ) {
return true;
}
}
@@ -430,10 +485,18 @@
// Check if a tag in the universe is allowed.
let filterRule;
let tag;
- for (let l = 0; !_.isEmpty(universe) && l < filterStatus.rules.length; l++) {
+ for (
+ let l = 0;
+ !_.isEmpty(universe) && l < filterStatus.rules.length;
+ l++
+ ) {
filterRule = filterStatus.rules[l];
if (filterRule.allow === true) {
- for (let m = 0; !_.isEmpty(universe) && m < filterRule.tags.length; m++) {
+ for (
+ let m = 0;
+ !_.isEmpty(universe) && m < filterRule.tags.length;
+ m++
+ ) {
tag = filterRule.tags[m];
if (_.has(universe, tag)) {
universe[tag].tag = true;
@@ -445,12 +508,23 @@
// Check if a property value of a tag in the universe is allowed.
// For all filter rules…
- for (let i = 0; !_.isEmpty(universe) && i < filterStatus.rules.length; i++) {
+ for (
+ let i = 0;
+ !_.isEmpty(universe) && i < filterStatus.rules.length;
+ i++
+ ) {
filterRule = filterStatus.rules[i];
// … if there are tags with restricted property values …
- if (filterRule.restrictedTags.tags.length && !emptyProperties(filterRule.restrictedTags.allowed)) {
+ if (
+ filterRule.restrictedTags.tags.length &&
+ !emptyProperties(filterRule.restrictedTags.allowed)
+ ) {
// … for all those tags …
- for (let j = 0; !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length; j++) {
+ for (
+ let j = 0;
+ !_.isEmpty(universe) && j < filterRule.restrictedTags.tags.length;
+ j++
+ ) {
tag = filterRule.restrictedTags.tags[j];
// … then iterate over all properties …
for (let k = 0; k < properties.length; k++) {
@@ -459,7 +533,15 @@
// of the allowed property values for this tag and property is
// listed in the universe. (Because everything might be allowed
// now.)
- if (findPropertyValuesOnTag(universe, tag, property, filterRule.restrictedTags.allowed[property], true)) {
+ if (
+ findPropertyValuesOnTag(
+ universe,
+ tag,
+ property,
+ filterRule.restrictedTags.allowed[property],
+ true,
+ )
+ ) {
deleteFromUniverseIfAllowed(universe, tag);
}
}
@@ -569,10 +651,12 @@
// If any filter's current status forbids the editor feature, return
// false.
Drupal.filterConfiguration.update();
- return Object.keys(Drupal.filterConfiguration.statuses)
- .every(filterID => (
- filterStatusAllowsFeature(Drupal.filterConfiguration.statuses[filterID], feature)
- ));
+ return Object.keys(Drupal.filterConfiguration.statuses).every(filterID =>
+ filterStatusAllowsFeature(
+ Drupal.filterConfiguration.statuses[filterID],
+ feature,
+ ),
+ );
},
};
@@ -607,7 +691,7 @@
*
* @see Drupal.EditorFeature
*/
- Drupal.EditorFeatureHTMLRule = function () {
+ Drupal.EditorFeatureHTMLRule = function() {
/**
*
* @type {Object}
@@ -673,7 +757,7 @@
*
* @see Drupal.EditorFeatureHTMLRule
*/
- Drupal.EditorFeature = function (name) {
+ Drupal.EditorFeature = function(name) {
this.name = name;
this.rules = [];
};
@@ -684,7 +768,7 @@
* @param {Drupal.EditorFeatureHTMLRule} rule
* A text editor feature HTML rule.
*/
- Drupal.EditorFeature.prototype.addHTMLRule = function (rule) {
+ Drupal.EditorFeature.prototype.addHTMLRule = function(rule) {
this.rules.push(rule);
};
@@ -711,7 +795,7 @@
*
* @see Drupal.FilterHTMLRule
*/
- Drupal.FilterStatus = function (name) {
+ Drupal.FilterStatus = function(name) {
/**
*
* @type {string}
@@ -737,7 +821,7 @@
* @param {Drupal.FilterHTMLRule} rule
* A text filter HTML rule.
*/
- Drupal.FilterStatus.prototype.addHTMLRule = function (rule) {
+ Drupal.FilterStatus.prototype.addHTMLRule = function(rule) {
this.rules.push(rule);
};
@@ -816,7 +900,7 @@
*
* @see Drupal.FilterStatus
*/
- Drupal.FilterHTMLRule = function () {
+ Drupal.FilterHTMLRule = function() {
// Allow or forbid tags.
this.tags = [];
this.allow = null;
@@ -831,17 +915,29 @@
return this;
};
- Drupal.FilterHTMLRule.prototype.clone = function () {
+ Drupal.FilterHTMLRule.prototype.clone = function() {
const clone = new Drupal.FilterHTMLRule();
clone.tags = this.tags.slice(0);
clone.allow = this.allow;
clone.restrictedTags.tags = this.restrictedTags.tags.slice(0);
- clone.restrictedTags.allowed.attributes = this.restrictedTags.allowed.attributes.slice(0);
- clone.restrictedTags.allowed.styles = this.restrictedTags.allowed.styles.slice(0);
- clone.restrictedTags.allowed.classes = this.restrictedTags.allowed.classes.slice(0);
- clone.restrictedTags.forbidden.attributes = this.restrictedTags.forbidden.attributes.slice(0);
- clone.restrictedTags.forbidden.styles = this.restrictedTags.forbidden.styles.slice(0);
- clone.restrictedTags.forbidden.classes = this.restrictedTags.forbidden.classes.slice(0);
+ clone.restrictedTags.allowed.attributes = this.restrictedTags.allowed.attributes.slice(
+ 0,
+ );
+ clone.restrictedTags.allowed.styles = this.restrictedTags.allowed.styles.slice(
+ 0,
+ );
+ clone.restrictedTags.allowed.classes = this.restrictedTags.allowed.classes.slice(
+ 0,
+ );
+ clone.restrictedTags.forbidden.attributes = this.restrictedTags.forbidden.attributes.slice(
+ 0,
+ );
+ clone.restrictedTags.forbidden.styles = this.restrictedTags.forbidden.styles.slice(
+ 0,
+ );
+ clone.restrictedTags.forbidden.classes = this.restrictedTags.forbidden.classes.slice(
+ 0,
+ );
return clone;
};
@@ -852,7 +948,6 @@
* @namespace
*/
Drupal.filterConfiguration = {
-
/**
* Drupal.FilterStatus objects, keyed by filter ID.
*
@@ -885,17 +980,24 @@
* up-to-date.
*/
update() {
- Object.keys(Drupal.filterConfiguration.statuses || {}).forEach((filterID) => {
- // Update status.
- Drupal.filterConfiguration.statuses[filterID].active = $(`[name="filters[${filterID}][status]"]`).is(':checked');
+ Object.keys(Drupal.filterConfiguration.statuses || {}).forEach(
+ filterID => {
+ // Update status.
+ Drupal.filterConfiguration.statuses[filterID].active = $(
+ `[name="filters[${filterID}][status]"]`,
+ ).is(':checked');
- // Update current rules.
- if (Drupal.filterConfiguration.liveSettingParsers[filterID]) {
- Drupal.filterConfiguration.statuses[filterID].rules = Drupal.filterConfiguration.liveSettingParsers[filterID].getRules();
- }
- });
+ // Update current rules.
+ if (Drupal.filterConfiguration.liveSettingParsers[filterID]) {
+ Drupal.filterConfiguration.statuses[
+ filterID
+ ].rules = Drupal.filterConfiguration.liveSettingParsers[
+ filterID
+ ].getRules();
+ }
+ },
+ );
},
-
};
/**
@@ -910,19 +1012,27 @@
attach(context, settings) {
const $context = $(context);
- $context.find('#filters-status-wrapper input.form-checkbox').once('filter-editor-status').each(function () {
- const $checkbox = $(this);
- const nameAttribute = $checkbox.attr('name');
+ $context
+ .find('#filters-status-wrapper input.form-checkbox')
+ .once('filter-editor-status')
+ .each(function() {
+ const $checkbox = $(this);
+ const nameAttribute = $checkbox.attr('name');
- // The filter's checkbox has a name attribute of the form
- // "filters[<name of filter>][status]", parse "<name of filter>"
- // from it.
- const filterID = nameAttribute.substring(8, nameAttribute.indexOf(']'));
+ // The filter's checkbox has a name attribute of the form
+ // "filters[<name of filter>][status]", parse "<name of filter>"
+ // from it.
+ const filterID = nameAttribute.substring(
+ 8,
+ nameAttribute.indexOf(']'),
+ );
- // Create a Drupal.FilterStatus object to track the state (whether it's
- // active or not and its current settings, if any) of each filter.
- Drupal.filterConfiguration.statuses[filterID] = new Drupal.FilterStatus(filterID);
- });
+ // Create a Drupal.FilterStatus object to track the state (whether it's
+ // active or not and its current settings, if any) of each filter.
+ Drupal.filterConfiguration.statuses[
+ filterID
+ ] = new Drupal.FilterStatus(filterID);
+ });
},
};
-}(jQuery, _, Drupal, document));
+})(jQuery, _, Drupal, document);
diff --git a/core/modules/editor/js/editor.dialog.es6.js b/core/modules/editor/js/editor.dialog.es6.js
index 498ee28..dda4860 100644
--- a/core/modules/editor/js/editor.dialog.es6.js
+++ b/core/modules/editor/js/editor.dialog.es6.js
@@ -3,7 +3,7 @@
* AJAX commands used by Editor module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Command to save the contents of an editor-provided modal.
*
@@ -24,7 +24,11 @@
*
* @fires event:editor:dialogsave
*/
- Drupal.AjaxCommands.prototype.editorDialogSave = function (ajax, response, status) {
+ Drupal.AjaxCommands.prototype.editorDialogSave = function(
+ ajax,
+ response,
+ status,
+ ) {
$(window).trigger('editor:dialogsave', [response.values]);
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/editor/js/editor.es6.js b/core/modules/editor/js/editor.es6.js
index f3fe389..2ce678f 100644
--- a/core/modules/editor/js/editor.es6.js
+++ b/core/modules/editor/js/editor.es6.js
@@ -3,7 +3,7 @@
* Attaches behavior for the Editor module.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* Finds the text area field associated with the given text format selector.
*
@@ -71,11 +71,16 @@
* format will be attached.
*/
function changeTextEditor(field, newFormatID) {
- const previousFormatID = field.getAttribute('data-editor-active-text-format');
+ const previousFormatID = field.getAttribute(
+ 'data-editor-active-text-format',
+ );
// Detach the current editor (if any) and attach a new editor.
if (drupalSettings.editor.formats[previousFormatID]) {
- Drupal.editorDetach(field, drupalSettings.editor.formats[previousFormatID]);
+ Drupal.editorDetach(
+ field,
+ drupalSettings.editor.formats[previousFormatID],
+ );
}
// When no text editor is currently active, stop tracking changes.
else {
@@ -85,7 +90,12 @@
// Attach the new text editor (if any).
if (drupalSettings.editor.formats[newFormatID]) {
const format = drupalSettings.editor.formats[newFormatID];
- filterXssWhenSwitching(field, format, previousFormatID, Drupal.editorAttach);
+ filterXssWhenSwitching(
+ field,
+ format,
+ previousFormatID,
+ Drupal.editorAttach,
+ );
}
// Store the new active format.
@@ -113,13 +123,18 @@
// with it that supports content filtering, then first ask for
// confirmation, because switching text formats might cause certain
// markup to be stripped away.
- const supportContentFiltering = drupalSettings.editor.formats[newFormatID] && drupalSettings.editor.formats[newFormatID].editorSupportsContentFiltering;
+ const supportContentFiltering =
+ drupalSettings.editor.formats[newFormatID] &&
+ drupalSettings.editor.formats[newFormatID].editorSupportsContentFiltering;
// If there is no content yet, it's always safe to change the text format.
const hasContent = field.value !== '';
if (hasContent && supportContentFiltering) {
- const message = Drupal.t('Changing the text format to %text_format will permanently remove content that is not allowed in that text format.<br><br>Save your changes before switching the text format to avoid losing data.', {
- '%text_format': $select.find('option:selected').text(),
- });
+ const message = Drupal.t(
+ 'Changing the text format to %text_format will permanently remove content that is not allowed in that text format.<br><br>Save your changes before switching the text format to avoid losing data.',
+ {
+ '%text_format': $select.find('option:selected').text(),
+ },
+ );
const confirmationDialog = Drupal.dialog(`<div>${message}</div>`, {
title: Drupal.t('Change text format?'),
dialogClass: 'editor-change-text-format-modal',
@@ -150,7 +165,10 @@
// as per http://stackoverflow.com/a/5438771.
closeOnEscape: false,
create() {
- $(this).parent().find('.ui-dialog-titlebar-close').remove();
+ $(this)
+ .parent()
+ .find('.ui-dialog-titlebar-close')
+ .remove();
},
beforeClose: false,
close(event) {
@@ -160,8 +178,7 @@
});
confirmationDialog.showModal();
- }
- else {
+ } else {
changeTextEditor(field, newFormatID);
}
}
@@ -190,50 +207,57 @@
return;
}
- $(context).find('[data-editor-for]').once('editor').each(function () {
- const $this = $(this);
- const field = findFieldForFormatSelector($this);
-
- // Opt-out if no supported text area was found.
- if (!field) {
- return;
- }
-
- // Store the current active format.
- const activeFormatID = $this.val();
- field.setAttribute('data-editor-active-text-format', activeFormatID);
-
- // Directly attach this text editor, if the text format is enabled.
- if (settings.editor.formats[activeFormatID]) {
- // XSS protection for the current text format/editor is performed on
- // the server side, so we don't need to do anything special here.
- Drupal.editorAttach(field, settings.editor.formats[activeFormatID]);
- }
- // When there is no text editor for this text format, still track
- // changes, because the user has the ability to switch to some text
- // editor, otherwise this code would not be executed.
- $(field).on('change.editor keypress.editor', () => {
- field.setAttribute('data-editor-value-is-changed', 'true');
- // Just knowing that the value was changed is enough, stop tracking.
- $(field).off('.editor');
- });
+ $(context)
+ .find('[data-editor-for]')
+ .once('editor')
+ .each(function() {
+ const $this = $(this);
+ const field = findFieldForFormatSelector($this);
- // Attach onChange handler to text format selector element.
- if ($this.is('select')) {
- $this.on('change.editorAttach', { field }, onTextFormatChange);
- }
- // Detach any editor when the containing form is submitted.
- $this.parents('form').on('submit', (event) => {
- // Do not detach if the event was canceled.
- if (event.isDefaultPrevented()) {
+ // Opt-out if no supported text area was found.
+ if (!field) {
return;
}
- // Detach the current editor (if any).
+
+ // Store the current active format.
+ const activeFormatID = $this.val();
+ field.setAttribute('data-editor-active-text-format', activeFormatID);
+
+ // Directly attach this text editor, if the text format is enabled.
if (settings.editor.formats[activeFormatID]) {
- Drupal.editorDetach(field, settings.editor.formats[activeFormatID], 'serialize');
+ // XSS protection for the current text format/editor is performed on
+ // the server side, so we don't need to do anything special here.
+ Drupal.editorAttach(field, settings.editor.formats[activeFormatID]);
+ }
+ // When there is no text editor for this text format, still track
+ // changes, because the user has the ability to switch to some text
+ // editor, otherwise this code would not be executed.
+ $(field).on('change.editor keypress.editor', () => {
+ field.setAttribute('data-editor-value-is-changed', 'true');
+ // Just knowing that the value was changed is enough, stop tracking.
+ $(field).off('.editor');
+ });
+
+ // Attach onChange handler to text format selector element.
+ if ($this.is('select')) {
+ $this.on('change.editorAttach', { field }, onTextFormatChange);
}
+ // Detach any editor when the containing form is submitted.
+ $this.parents('form').on('submit', event => {
+ // Do not detach if the event was canceled.
+ if (event.isDefaultPrevented()) {
+ return;
+ }
+ // Detach the current editor (if any).
+ if (settings.editor.formats[activeFormatID]) {
+ Drupal.editorDetach(
+ field,
+ settings.editor.formats[activeFormatID],
+ 'serialize',
+ );
+ }
+ });
});
- });
},
detach(context, settings, trigger) {
@@ -243,18 +267,25 @@
if (trigger === 'serialize') {
// Removing the editor-processed class guarantees that the editor will
// be reattached. Only do this if we're planning to destroy the editor.
- editors = $(context).find('[data-editor-for]').findOnce('editor');
- }
- else {
- editors = $(context).find('[data-editor-for]').removeOnce('editor');
+ editors = $(context)
+ .find('[data-editor-for]')
+ .findOnce('editor');
+ } else {
+ editors = $(context)
+ .find('[data-editor-for]')
+ .removeOnce('editor');
}
- editors.each(function () {
+ editors.each(function() {
const $this = $(this);
const activeFormatID = $this.val();
const field = findFieldForFormatSelector($this);
if (field && activeFormatID in settings.editor.formats) {
- Drupal.editorDetach(field, settings.editor.formats[activeFormatID], trigger);
+ Drupal.editorDetach(
+ field,
+ settings.editor.formats[activeFormatID],
+ trigger,
+ );
}
});
},
@@ -273,7 +304,7 @@
*
* @fires event:formUpdated
*/
- Drupal.editorAttach = function (field, format) {
+ Drupal.editorAttach = function(field, format) {
if (format.editor) {
// Attach the text editor.
Drupal.editors[format.editor].attach(field, format);
@@ -301,7 +332,7 @@
* @param {string} trigger
* Trigger value from the detach behavior.
*/
- Drupal.editorDetach = function (field, format, trigger) {
+ Drupal.editorDetach = function(field, format, trigger) {
if (format.editor) {
Drupal.editors[format.editor].detach(field, format, trigger);
@@ -311,4 +342,4 @@
}
}
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/editor/js/editor.formattedTextEditor.es6.js b/core/modules/editor/js/editor.formattedTextEditor.es6.js
index 4851548..d4296ff 100644
--- a/core/modules/editor/js/editor.formattedTextEditor.es6.js
+++ b/core/modules/editor/js/editor.formattedTextEditor.es6.js
@@ -11,223 +11,234 @@
* - Drupal.editors.magical.attachInlineEditor()
*/
-(function ($, Drupal, drupalSettings, _) {
- Drupal.quickedit.editors.editor = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.editor# */{
-
- /**
- * The text format for this field.
- *
- * @type {string}
- */
- textFormat: null,
-
- /**
- * Indicates whether this text format has transformations.
- *
- * @type {bool}
- */
- textFormatHasTransformations: null,
-
- /**
- * Stores a reference to the text editor object for this field.
- *
- * @type {Drupal.quickedit.EditorModel}
- */
- textEditor: null,
-
- /**
- * Stores the textual DOM element that is being in-place edited.
- *
- * @type {jQuery}
- */
- $textElement: null,
-
- /**
- * @constructs
- *
- * @augments Drupal.quickedit.EditorView
- *
- * @param {object} options
- * Options for the editor view.
- */
- initialize(options) {
- Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
-
- const metadata = Drupal.quickedit.metadata.get(this.fieldModel.get('fieldID'), 'custom');
- this.textFormat = drupalSettings.editor.formats[metadata.format];
- this.textFormatHasTransformations = metadata.formatHasTransformations;
- this.textEditor = Drupal.editors[this.textFormat.editor];
-
- // Store the actual value of this field. We'll need this to restore the
- // original value when the user discards his modifications.
- const $fieldItems = this.$el.find('.quickedit-field');
- if ($fieldItems.length) {
- this.$textElement = $fieldItems.eq(0);
- }
- else {
- this.$textElement = this.$el;
- }
- this.model.set('originalValue', this.$textElement.html());
- },
-
- /**
- * @inheritdoc
- *
- * @return {jQuery}
- * The text element edited.
- */
- getEditedElement() {
- return this.$textElement;
- },
-
- /**
- * @inheritdoc
- *
- * @param {object} fieldModel
- * The field model.
- * @param {string} state
- * The current state.
- */
- stateChange(fieldModel, state) {
- const editorModel = this.model;
- const from = fieldModel.previous('state');
- const to = state;
- switch (to) {
- case 'inactive':
- break;
-
- case 'candidate':
- // Detach the text editor when entering the 'candidate' state from one
- // of the states where it could have been attached.
- if (from !== 'inactive' && from !== 'highlighted') {
- this.textEditor.detach(this.$textElement.get(0), this.textFormat);
- }
- // A field model's editor view revert() method is invoked when an
- // 'active' field becomes a 'candidate' field. But, in the case of
- // this in-place editor, the content will have been *replaced* if the
- // text format has transformation filters. Therefore, if we stop
- // in-place editing this entity, revert explicitly.
- if (from === 'active' && this.textFormatHasTransformations) {
- this.revert();
- }
- if (from === 'invalid') {
- this.removeValidationErrors();
- }
- break;
-
- case 'highlighted':
- break;
-
- case 'activating':
- // When transformation filters have been applied to the formatted text
- // of this field, then we'll need to load a re-formatted version of it
- // without the transformation filters.
- if (this.textFormatHasTransformations) {
- const $textElement = this.$textElement;
- this._getUntransformedText((untransformedText) => {
- $textElement.html(untransformedText);
- fieldModel.set('state', 'active');
- });
- }
- // When no transformation filters have been applied: start WYSIWYG
- // editing immediately!
- else {
- // Defer updating the model until the current state change has
- // propagated, to not trigger a nested state change event.
- _.defer(() => {
- fieldModel.set('state', 'active');
- });
- }
- break;
-
- case 'active': {
- const textElement = this.$textElement.get(0);
- const toolbarView = fieldModel.toolbarView;
- this.textEditor.attachInlineEditor(
- textElement,
- this.textFormat,
- toolbarView.getMainWysiwygToolgroupId(),
- toolbarView.getFloatedWysiwygToolgroupId(),
- );
- // Set the state to 'changed' whenever the content has changed.
- this.textEditor.onChange(textElement, (htmlText) => {
- editorModel.set('currentValue', htmlText);
- fieldModel.set('state', 'changed');
- });
- break;
+(function($, Drupal, drupalSettings, _) {
+ Drupal.quickedit.editors.editor = Drupal.quickedit.EditorView.extend(
+ /** @lends Drupal.quickedit.editors.editor# */ {
+ /**
+ * The text format for this field.
+ *
+ * @type {string}
+ */
+ textFormat: null,
+
+ /**
+ * Indicates whether this text format has transformations.
+ *
+ * @type {bool}
+ */
+ textFormatHasTransformations: null,
+
+ /**
+ * Stores a reference to the text editor object for this field.
+ *
+ * @type {Drupal.quickedit.EditorModel}
+ */
+ textEditor: null,
+
+ /**
+ * Stores the textual DOM element that is being in-place edited.
+ *
+ * @type {jQuery}
+ */
+ $textElement: null,
+
+ /**
+ * @constructs
+ *
+ * @augments Drupal.quickedit.EditorView
+ *
+ * @param {object} options
+ * Options for the editor view.
+ */
+ initialize(options) {
+ Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
+
+ const metadata = Drupal.quickedit.metadata.get(
+ this.fieldModel.get('fieldID'),
+ 'custom',
+ );
+ this.textFormat = drupalSettings.editor.formats[metadata.format];
+ this.textFormatHasTransformations = metadata.formatHasTransformations;
+ this.textEditor = Drupal.editors[this.textFormat.editor];
+
+ // Store the actual value of this field. We'll need this to restore the
+ // original value when the user discards his modifications.
+ const $fieldItems = this.$el.find('.quickedit-field');
+ if ($fieldItems.length) {
+ this.$textElement = $fieldItems.eq(0);
+ } else {
+ this.$textElement = this.$el;
}
-
- case 'changed':
- break;
-
- case 'saving':
- if (from === 'invalid') {
- this.removeValidationErrors();
+ this.model.set('originalValue', this.$textElement.html());
+ },
+
+ /**
+ * @inheritdoc
+ *
+ * @return {jQuery}
+ * The text element edited.
+ */
+ getEditedElement() {
+ return this.$textElement;
+ },
+
+ /**
+ * @inheritdoc
+ *
+ * @param {object} fieldModel
+ * The field model.
+ * @param {string} state
+ * The current state.
+ */
+ stateChange(fieldModel, state) {
+ const editorModel = this.model;
+ const from = fieldModel.previous('state');
+ const to = state;
+ switch (to) {
+ case 'inactive':
+ break;
+
+ case 'candidate':
+ // Detach the text editor when entering the 'candidate' state from one
+ // of the states where it could have been attached.
+ if (from !== 'inactive' && from !== 'highlighted') {
+ this.textEditor.detach(this.$textElement.get(0), this.textFormat);
+ }
+ // A field model's editor view revert() method is invoked when an
+ // 'active' field becomes a 'candidate' field. But, in the case of
+ // this in-place editor, the content will have been *replaced* if the
+ // text format has transformation filters. Therefore, if we stop
+ // in-place editing this entity, revert explicitly.
+ if (from === 'active' && this.textFormatHasTransformations) {
+ this.revert();
+ }
+ if (from === 'invalid') {
+ this.removeValidationErrors();
+ }
+ break;
+
+ case 'highlighted':
+ break;
+
+ case 'activating':
+ // When transformation filters have been applied to the formatted text
+ // of this field, then we'll need to load a re-formatted version of it
+ // without the transformation filters.
+ if (this.textFormatHasTransformations) {
+ const $textElement = this.$textElement;
+ this._getUntransformedText(untransformedText => {
+ $textElement.html(untransformedText);
+ fieldModel.set('state', 'active');
+ });
+ }
+ // When no transformation filters have been applied: start WYSIWYG
+ // editing immediately!
+ else {
+ // Defer updating the model until the current state change has
+ // propagated, to not trigger a nested state change event.
+ _.defer(() => {
+ fieldModel.set('state', 'active');
+ });
+ }
+ break;
+
+ case 'active': {
+ const textElement = this.$textElement.get(0);
+ const toolbarView = fieldModel.toolbarView;
+ this.textEditor.attachInlineEditor(
+ textElement,
+ this.textFormat,
+ toolbarView.getMainWysiwygToolgroupId(),
+ toolbarView.getFloatedWysiwygToolgroupId(),
+ );
+ // Set the state to 'changed' whenever the content has changed.
+ this.textEditor.onChange(textElement, htmlText => {
+ editorModel.set('currentValue', htmlText);
+ fieldModel.set('state', 'changed');
+ });
+ break;
}
- this.save();
- break;
-
- case 'saved':
- break;
- case 'invalid':
- this.showValidationErrors();
- break;
- }
- },
+ case 'changed':
+ break;
- /**
- * @inheritdoc
- *
- * @return {object}
- * The settings for the quick edit UI.
- */
- getQuickEditUISettings() {
- return {
- padding: true,
- unifiedToolbar: true,
- fullWidthToolbar: true,
- popup: false,
- };
- },
+ case 'saving':
+ if (from === 'invalid') {
+ this.removeValidationErrors();
+ }
+ this.save();
+ break;
- /**
- * @inheritdoc
- */
- revert() {
- this.$textElement.html(this.model.get('originalValue'));
- },
+ case 'saved':
+ break;
- /**
- * Loads untransformed text for this field.
- *
- * More accurately: it re-filters formatted text to exclude transformation
- * filters used by the text format.
- *
- * @param {function} callback
- * A callback function that will receive the untransformed text.
- *
- * @see \Drupal\editor\Ajax\GetUntransformedTextCommand
- */
- _getUntransformedText(callback) {
- const fieldID = this.fieldModel.get('fieldID');
-
- // Create a Drupal.ajax instance to load the form.
- const textLoaderAjax = Drupal.ajax({
- url: Drupal.quickedit.util.buildUrl(fieldID, Drupal.url('editor/!entity_type/!id/!field_name/!langcode/!view_mode')),
- submit: { nocssjs: true },
- });
-
- // Implement a scoped editorGetUntransformedText AJAX command: calls the
- // callback.
- textLoaderAjax.commands.editorGetUntransformedText = function (ajax, response, status) {
- callback(response.data);
- };
-
- // This will ensure our scoped editorGetUntransformedText AJAX command
- // gets called.
- textLoaderAjax.execute();
+ case 'invalid':
+ this.showValidationErrors();
+ break;
+ }
+ },
+
+ /**
+ * @inheritdoc
+ *
+ * @return {object}
+ * The settings for the quick edit UI.
+ */
+ getQuickEditUISettings() {
+ return {
+ padding: true,
+ unifiedToolbar: true,
+ fullWidthToolbar: true,
+ popup: false,
+ };
+ },
+
+ /**
+ * @inheritdoc
+ */
+ revert() {
+ this.$textElement.html(this.model.get('originalValue'));
+ },
+
+ /**
+ * Loads untransformed text for this field.
+ *
+ * More accurately: it re-filters formatted text to exclude transformation
+ * filters used by the text format.
+ *
+ * @param {function} callback
+ * A callback function that will receive the untransformed text.
+ *
+ * @see \Drupal\editor\Ajax\GetUntransformedTextCommand
+ */
+ _getUntransformedText(callback) {
+ const fieldID = this.fieldModel.get('fieldID');
+
+ // Create a Drupal.ajax instance to load the form.
+ const textLoaderAjax = Drupal.ajax({
+ url: Drupal.quickedit.util.buildUrl(
+ fieldID,
+ Drupal.url(
+ 'editor/!entity_type/!id/!field_name/!langcode/!view_mode',
+ ),
+ ),
+ submit: { nocssjs: true },
+ });
+
+ // Implement a scoped editorGetUntransformedText AJAX command: calls the
+ // callback.
+ textLoaderAjax.commands.editorGetUntransformedText = function(
+ ajax,
+ response,
+ status,
+ ) {
+ callback(response.data);
+ };
+
+ // This will ensure our scoped editorGetUntransformedText AJAX command
+ // gets called.
+ textLoaderAjax.execute();
+ },
},
-
- });
-}(jQuery, Drupal, drupalSettings, _));
+ );
+})(jQuery, Drupal, drupalSettings, _);
diff --git a/core/modules/field_ui/field_ui.es6.js b/core/modules/field_ui/field_ui.es6.js
index bed88de..e183704 100644
--- a/core/modules/field_ui/field_ui.es6.js
+++ b/core/modules/field_ui/field_ui.es6.js
@@ -3,7 +3,7 @@
* Attaches the behaviors for the Field UI module.
*/
-(function ($, Drupal, drupalSettings) {
+(function($, Drupal, drupalSettings) {
/**
* @type {Drupal~behavior}
*
@@ -12,27 +12,34 @@
*/
Drupal.behaviors.fieldUIFieldStorageAddForm = {
attach(context) {
- const $form = $(context).find('[data-drupal-selector="field-ui-field-storage-add-form"]').once('field_ui_add');
+ const $form = $(context)
+ .find('[data-drupal-selector="field-ui-field-storage-add-form"]')
+ .once('field_ui_add');
if ($form.length) {
// Add a few 'js-form-required' and 'form-required' css classes here.
// We can not use the Form API '#required' property because both label
// elements for "add new" and "re-use existing" can never be filled and
// submitted at the same time. The actual validation will happen
// server-side.
- $form.find(
- '.js-form-item-label label,' +
- '.js-form-item-field-name label,' +
- '.js-form-item-existing-storage-label label',
- )
+ $form
+ .find(
+ '.js-form-item-label label,' +
+ '.js-form-item-field-name label,' +
+ '.js-form-item-existing-storage-label label',
+ )
.addClass('js-form-required form-required');
const $newFieldType = $form.find('select[name="new_storage_type"]');
- const $existingStorageName = $form.find('select[name="existing_storage_name"]');
- const $existingStorageLabel = $form.find('input[name="existing_storage_label"]');
+ const $existingStorageName = $form.find(
+ 'select[name="existing_storage_name"]',
+ );
+ const $existingStorageLabel = $form.find(
+ 'input[name="existing_storage_label"]',
+ );
// When the user selects a new field type, clear the "existing field"
// selection.
- $newFieldType.on('change', function () {
+ $newFieldType.on('change', function() {
if ($(this).val() !== '') {
// Reset the "existing storage name" selection.
$existingStorageName.val('').trigger('change');
@@ -41,15 +48,19 @@
// When the user selects an existing storage name, clear the "new field
// type" selection and populate the 'existing_storage_label' element.
- $existingStorageName.on('change', function () {
+ $existingStorageName.on('change', function() {
const value = $(this).val();
if (value !== '') {
// Reset the "new field type" selection.
$newFieldType.val('').trigger('change');
// Pre-populate the "existing storage label" element.
- if (typeof drupalSettings.existingFieldLabels[value] !== 'undefined') {
- $existingStorageLabel.val(drupalSettings.existingFieldLabels[value]);
+ if (
+ typeof drupalSettings.existingFieldLabels[value] !== 'undefined'
+ ) {
+ $existingStorageLabel.val(
+ drupalSettings.existingFieldLabels[value],
+ );
}
}
});
@@ -69,9 +80,16 @@
*/
Drupal.behaviors.fieldUIDisplayOverview = {
attach(context, settings) {
- $(context).find('table#field-display-overview').once('field-display-overview').each(function () {
- Drupal.fieldUIOverview.attach(this, settings.fieldUIRowsData, Drupal.fieldUIDisplayOverview);
- });
+ $(context)
+ .find('table#field-display-overview')
+ .once('field-display-overview')
+ .each(function() {
+ Drupal.fieldUIOverview.attach(
+ this,
+ settings.fieldUIRowsData,
+ Drupal.fieldUIDisplayOverview,
+ );
+ });
},
};
@@ -81,7 +99,6 @@
* @namespace
*/
Drupal.fieldUIOverview = {
-
/**
* Attaches the fieldUIOverview behavior.
*
@@ -100,19 +117,21 @@
tableDrag.row.prototype.onSwap = this.onSwap;
// Create row handlers.
- $(table).find('tr.draggable').each(function () {
- // Extract server-side data for the row.
- const row = this;
- if (row.id in rowsData) {
- const data = rowsData[row.id];
- data.tableDrag = tableDrag;
-
- // Create the row handler, make it accessible from the DOM row
- // element.
- const rowHandler = new rowHandlers[data.rowHandler](row, data);
- $(row).data('fieldUIRowHandler', rowHandler);
- }
- });
+ $(table)
+ .find('tr.draggable')
+ .each(function() {
+ // Extract server-side data for the row.
+ const row = this;
+ if (row.id in rowsData) {
+ const data = rowsData[row.id];
+ data.tableDrag = tableDrag;
+
+ // Create the row handler, make it accessible from the DOM row
+ // element.
+ const rowHandler = new rowHandlers[data.rowHandler](row, data);
+ $(row).data('fieldUIRowHandler', rowHandler);
+ }
+ });
},
/**
@@ -151,7 +170,10 @@
const rowHandler = $row.data('fieldUIRowHandler');
if (typeof rowHandler !== 'undefined') {
const regionRow = $row.prevAll('tr.region-message').get(0);
- const region = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
+ const region = regionRow.className.replace(
+ /([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/,
+ '$2',
+ );
if (region !== rowHandler.region) {
// Let the row handler deal with the region change.
@@ -174,26 +196,37 @@
*/
onSwap(draggedRow) {
const rowObject = this;
- $(rowObject.table).find('tr.region-message').each(function () {
- const $this = $(this);
- // If the dragged row is in this region, but above the message row, swap
- // it down one space.
- if ($this.prev('tr').get(0) === rowObject.group[rowObject.group.length - 1]) {
- // Prevent a recursion problem when using the keyboard to move rows
- // up.
- if ((rowObject.method !== 'keyboard' || rowObject.direction === 'down')) {
- rowObject.swap('after', this);
+ $(rowObject.table)
+ .find('tr.region-message')
+ .each(function() {
+ const $this = $(this);
+ // If the dragged row is in this region, but above the message row, swap
+ // it down one space.
+ if (
+ $this.prev('tr').get(0) ===
+ rowObject.group[rowObject.group.length - 1]
+ ) {
+ // Prevent a recursion problem when using the keyboard to move rows
+ // up.
+ if (
+ rowObject.method !== 'keyboard' ||
+ rowObject.direction === 'down'
+ ) {
+ rowObject.swap('after', this);
+ }
}
- }
- // This region has become empty.
- if ($this.next('tr').is(':not(.draggable)') || $this.next('tr').length === 0) {
- $this.removeClass('region-populated').addClass('region-empty');
- }
- // This region has become populated.
- else if ($this.is('.region-empty')) {
- $this.removeClass('region-empty').addClass('region-populated');
- }
- });
+ // This region has become empty.
+ if (
+ $this.next('tr').is(':not(.draggable)') ||
+ $this.next('tr').length === 0
+ ) {
+ $this.removeClass('region-populated').addClass('region-empty');
+ }
+ // This region has become populated.
+ else if ($this.is('.region-empty')) {
+ $this.removeClass('region-empty').addClass('region-populated');
+ }
+ });
},
/**
@@ -213,7 +246,7 @@
// Separate keys and values.
const rowNames = [];
const ajaxElements = [];
- Object.keys(rows || {}).forEach((rowName) => {
+ Object.keys(rows || {}).forEach(rowName => {
rowNames.push(rowName);
ajaxElements.push(rows[rowName]);
});
@@ -255,7 +288,7 @@
* @return {Drupal.fieldUIDisplayOverview.field}
* The field row handler constructed.
*/
- Drupal.fieldUIDisplayOverview.field = function (row, data) {
+ Drupal.fieldUIDisplayOverview.field = function(row, data) {
this.row = row;
this.name = data.name;
this.region = data.region;
@@ -274,7 +307,6 @@
};
Drupal.fieldUIDisplayOverview.field.prototype = {
-
/**
* Returns the region corresponding to the current form values of the row.
*
@@ -314,7 +346,10 @@
// Restore the formatter back to the default formatter. Pseudo-fields
// do not have default formatters, we just return to 'visible' for
// those.
- const value = (typeof this.defaultPlugin !== 'undefined') ? this.defaultPlugin : this.$pluginSelect.find('option').val();
+ const value =
+ typeof this.defaultPlugin !== 'undefined'
+ ? this.defaultPlugin
+ : this.$pluginSelect.find('option').val();
if (typeof value !== 'undefined') {
this.$pluginSelect.val(value);
@@ -326,4 +361,4 @@
return refreshRows;
},
};
-}(jQuery, Drupal, drupalSettings));
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/file/file.es6.js b/core/modules/file/file.es6.js
index 6923e95..762a18f 100644
--- a/core/modules/file/file.es6.js
+++ b/core/modules/file/file.es6.js
@@ -7,7 +7,7 @@
* prevents separate file fields from accidentally uploading files).
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Attach behaviors to the file fields passed in the settings.
*
@@ -24,9 +24,14 @@
let elements;
function initFileValidation(selector) {
- $context.find(selector)
+ $context
+ .find(selector)
.once('fileValidate')
- .on('change.fileValidate', { extensions: elements[selector] }, Drupal.file.validateExtension);
+ .on(
+ 'change.fileValidate',
+ { extensions: elements[selector] },
+ Drupal.file.validateExtension,
+ );
}
if (settings.file && settings.file.elements) {
@@ -39,7 +44,8 @@
let elements;
function removeFileValidation(selector) {
- $context.find(selector)
+ $context
+ .find(selector)
.removeOnce('fileValidate')
.off('change.fileValidate', Drupal.file.validateExtension);
}
@@ -63,11 +69,17 @@
*/
Drupal.behaviors.fileAutoUpload = {
attach(context) {
- $(context).find('input[type="file"]').once('auto-file-upload').on('change.autoFileUpload', Drupal.file.triggerUploadButton);
+ $(context)
+ .find('input[type="file"]')
+ .once('auto-file-upload')
+ .on('change.autoFileUpload', Drupal.file.triggerUploadButton);
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
- $(context).find('input[type="file"]').removeOnce('auto-file-upload').off('.autoFileUpload');
+ $(context)
+ .find('input[type="file"]')
+ .removeOnce('auto-file-upload')
+ .off('.autoFileUpload');
}
},
};
@@ -85,14 +97,22 @@
Drupal.behaviors.fileButtons = {
attach(context) {
const $context = $(context);
- $context.find('.js-form-submit').on('mousedown', Drupal.file.disableFields);
- $context.find('.js-form-managed-file .js-form-submit').on('mousedown', Drupal.file.progressBar);
+ $context
+ .find('.js-form-submit')
+ .on('mousedown', Drupal.file.disableFields);
+ $context
+ .find('.js-form-managed-file .js-form-submit')
+ .on('mousedown', Drupal.file.progressBar);
},
detach(context, settings, trigger) {
if (trigger === 'unload') {
const $context = $(context);
- $context.find('.js-form-submit').off('mousedown', Drupal.file.disableFields);
- $context.find('.js-form-managed-file .js-form-submit').off('mousedown', Drupal.file.progressBar);
+ $context
+ .find('.js-form-submit')
+ .off('mousedown', Drupal.file.disableFields);
+ $context
+ .find('.js-form-managed-file .js-form-submit')
+ .off('mousedown', Drupal.file.progressBar);
}
},
};
@@ -109,10 +129,14 @@
*/
Drupal.behaviors.filePreviewLinks = {
attach(context) {
- $(context).find('div.js-form-managed-file .file a').on('click', Drupal.file.openInNewWindow);
+ $(context)
+ .find('div.js-form-managed-file .file a')
+ .on('click', Drupal.file.openInNewWindow);
},
detach(context) {
- $(context).find('div.js-form-managed-file .file a').off('click', Drupal.file.openInNewWindow);
+ $(context)
+ .find('div.js-form-managed-file .file a')
+ .off('click', Drupal.file.openInNewWindow);
},
};
@@ -122,7 +146,6 @@
* @namespace
*/
Drupal.file = Drupal.file || {
-
/**
* Client-side file input validation of file extensions.
*
@@ -141,18 +164,25 @@
if (extensionPattern.length > 1 && this.value.length > 0) {
const acceptableMatch = new RegExp(`\\.(${extensionPattern})$`, 'gi');
if (!acceptableMatch.test(this.value)) {
- const error = Drupal.t('The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.', {
- // According to the specifications of HTML5, a file upload control
- // should not reveal the real local path to the file that a user
- // has selected. Some web browsers implement this restriction by
- // replacing the local path with "C:\fakepath\", which can cause
- // confusion by leaving the user thinking perhaps Drupal could not
- // find the file because it messed up the file path. To avoid this
- // confusion, therefore, we strip out the bogus fakepath string.
- '%filename': this.value.replace('C:\\fakepath\\', ''),
- '%extensions': extensionPattern.replace(/\|/g, ', '),
- });
- $(this).closest('div.js-form-managed-file').prepend(`<div class="messages messages--error file-upload-js-error" aria-live="polite">${error}</div>`);
+ const error = Drupal.t(
+ 'The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.',
+ {
+ // According to the specifications of HTML5, a file upload control
+ // should not reveal the real local path to the file that a user
+ // has selected. Some web browsers implement this restriction by
+ // replacing the local path with "C:\fakepath\", which can cause
+ // confusion by leaving the user thinking perhaps Drupal could not
+ // find the file because it messed up the file path. To avoid this
+ // confusion, therefore, we strip out the bogus fakepath string.
+ '%filename': this.value.replace('C:\\fakepath\\', ''),
+ '%extensions': extensionPattern.replace(/\|/g, ', '),
+ },
+ );
+ $(this)
+ .closest('div.js-form-managed-file')
+ .prepend(
+ `<div class="messages messages--error file-upload-js-error" aria-live="polite">${error}</div>`,
+ );
this.value = '';
// Cancel all other change event handlers.
event.stopImmediatePropagation();
@@ -169,7 +199,10 @@
* The event triggered. For example `change.autoFileUpload`.
*/
triggerUploadButton(event) {
- $(event.target).closest('.js-form-managed-file').find('.js-form-submit').trigger('mousedown');
+ $(event.target)
+ .closest('.js-form-managed-file')
+ .find('.js-form-submit')
+ .trigger('mousedown');
},
/**
@@ -186,7 +219,9 @@
// Check if we're working with an "Upload" button.
let $enabledFields = [];
if ($clickedButton.closest('div.js-form-managed-file').length > 0) {
- $enabledFields = $clickedButton.closest('div.js-form-managed-file').find('input.js-form-file');
+ $enabledFields = $clickedButton
+ .closest('div.js-form-managed-file')
+ .find('input.js-form-file');
}
// Temporarily disable upload fields other than the one we're currently
@@ -198,7 +233,11 @@
// functions are called, so we don't have to worry about the fields being
// re-enabled too soon. @todo If the previous sentence is true, why not
// set the timeout to 0?
- const $fieldsToTemporarilyDisable = $('div.js-form-managed-file input.js-form-file').not($enabledFields).not(':disabled');
+ const $fieldsToTemporarilyDisable = $(
+ 'div.js-form-managed-file input.js-form-file',
+ )
+ .not($enabledFields)
+ .not(':disabled');
$fieldsToTemporarilyDisable.prop('disabled', true);
setTimeout(() => {
$fieldsToTemporarilyDisable.prop('disabled', false);
@@ -215,12 +254,17 @@
*/
progressBar(event) {
const $clickedButton = $(this);
- const $progressId = $clickedButton.closest('div.js-form-managed-file').find('input.file-progress');
+ const $progressId = $clickedButton
+ .closest('div.js-form-managed-file')
+ .find('input.file-progress');
if ($progressId.length) {
const originalName = $progressId.attr('name');
// Replace the name with the required identifier.
- $progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
+ $progressId.attr(
+ 'name',
+ originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0],
+ );
// Restore the original name after the upload begins.
setTimeout(() => {
@@ -229,7 +273,10 @@
}
// Show the progress bar if the upload takes longer than half a second.
setTimeout(() => {
- $clickedButton.closest('div.js-form-managed-file').find('div.ajax-progress-bar').slideDown();
+ $clickedButton
+ .closest('div.js-form-managed-file')
+ .find('div.ajax-progress-bar')
+ .slideDown();
}, 500);
$clickedButton.trigger('fileUpload');
},
@@ -245,7 +292,11 @@
openInNewWindow(event) {
event.preventDefault();
$(this).attr('target', '_blank');
- window.open(this.href, 'filePreview', 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550');
+ window.open(
+ this.href,
+ 'filePreview',
+ 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550',
+ );
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/filter/filter.admin.es6.js b/core/modules/filter/filter.admin.es6.js
index 7c69fe0..fe2cca7 100644
--- a/core/modules/filter/filter.admin.es6.js
+++ b/core/modules/filter/filter.admin.es6.js
@@ -3,7 +3,7 @@
* Attaches administration-specific behavior for the Filter module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Displays and updates the status of filters on the admin page.
*
@@ -15,49 +15,58 @@
Drupal.behaviors.filterStatus = {
attach(context, settings) {
const $context = $(context);
- $context.find('#filters-status-wrapper input.form-checkbox').once('filter-status').each(function () {
- const $checkbox = $(this);
- // Retrieve the tabledrag row belonging to this filter.
- const $row = $context.find(`#${$checkbox.attr('id').replace(/-status$/, '-weight')}`).closest('tr');
- // Retrieve the vertical tab belonging to this filter.
- const $filterSettings = $context.find(`#${$checkbox.attr('id').replace(/-status$/, '-settings')}`);
- const filterSettingsTab = $filterSettings.data('verticalTab');
+ $context
+ .find('#filters-status-wrapper input.form-checkbox')
+ .once('filter-status')
+ .each(function() {
+ const $checkbox = $(this);
+ // Retrieve the tabledrag row belonging to this filter.
+ const $row = $context
+ .find(`#${$checkbox.attr('id').replace(/-status$/, '-weight')}`)
+ .closest('tr');
+ // Retrieve the vertical tab belonging to this filter.
+ const $filterSettings = $context.find(
+ `#${$checkbox.attr('id').replace(/-status$/, '-settings')}`,
+ );
+ const filterSettingsTab = $filterSettings.data('verticalTab');
- // Bind click handler to this checkbox to conditionally show and hide
- // the filter's tableDrag row and vertical tab pane.
- $checkbox.on('click.filterUpdate', () => {
- if ($checkbox.is(':checked')) {
- $row.show();
- if (filterSettingsTab) {
- filterSettingsTab.tabShow().updateSummary();
+ // Bind click handler to this checkbox to conditionally show and hide
+ // the filter's tableDrag row and vertical tab pane.
+ $checkbox.on('click.filterUpdate', () => {
+ if ($checkbox.is(':checked')) {
+ $row.show();
+ if (filterSettingsTab) {
+ filterSettingsTab.tabShow().updateSummary();
+ } else {
+ // On very narrow viewports, Vertical Tabs are disabled.
+ $filterSettings.show();
+ }
+ } else {
+ $row.hide();
+ if (filterSettingsTab) {
+ filterSettingsTab.tabHide().updateSummary();
+ } else {
+ // On very narrow viewports, Vertical Tabs are disabled.
+ $filterSettings.hide();
+ }
}
- else {
- // On very narrow viewports, Vertical Tabs are disabled.
- $filterSettings.show();
- }
- }
- else {
- $row.hide();
- if (filterSettingsTab) {
- filterSettingsTab.tabHide().updateSummary();
- }
- else {
- // On very narrow viewports, Vertical Tabs are disabled.
- $filterSettings.hide();
- }
- }
- // Restripe table after toggling visibility of table row.
- Drupal.tableDrag['filter-order'].restripeTable();
- });
+ // Restripe table after toggling visibility of table row.
+ Drupal.tableDrag['filter-order'].restripeTable();
+ });
- // Attach summary for configurable filters (only for screen readers).
- if (filterSettingsTab) {
- filterSettingsTab.details.drupalSetSummary(() => ($checkbox.is(':checked') ? Drupal.t('Enabled') : Drupal.t('Disabled')));
- }
+ // Attach summary for configurable filters (only for screen readers).
+ if (filterSettingsTab) {
+ filterSettingsTab.details.drupalSetSummary(
+ () =>
+ $checkbox.is(':checked')
+ ? Drupal.t('Enabled')
+ : Drupal.t('Disabled'),
+ );
+ }
- // Trigger our bound click handler to update elements to initial state.
- $checkbox.triggerHandler('click.filterUpdate');
- });
+ // Trigger our bound click handler to update elements to initial state.
+ $checkbox.triggerHandler('click.filterUpdate');
+ });
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/filter/filter.es6.js b/core/modules/filter/filter.es6.js
index e9550dd..330a53f 100644
--- a/core/modules/filter/filter.es6.js
+++ b/core/modules/filter/filter.es6.js
@@ -3,7 +3,7 @@
* Attaches behavior for the Filter module.
*/
-(function ($, Drupal) {
+(function($, Drupal) {
/**
* Displays the guidelines of the selected text format automatically.
*
@@ -38,4 +38,4 @@
.trigger('change.filterGuidelines');
},
};
-}(jQuery, Drupal));
+})(jQuery, Drupal);
diff --git a/core/modules/filter/filter.filter_html.admin.es6.js b/core/modules/filter/filter.filter_html.admin.es6.js
index 5480883..9c1bae0 100644
--- a/core/modules/filter/filter.filter_html.admin.es6.js
+++ b/core/modules/filter/filter.filter_html.admin.es6.js
@@ -3,7 +3,7 @@
* Attaches behavior for updating filter_html's settings automatically.
*/
-(function ($, Drupal, _, document) {
+(function($, Drupal, _, document) {
if (Drupal.filterConfiguration) {
/**
* Implement a live setting parser to prevent text editors from automatically
@@ -12,14 +12,17 @@
* @namespace
*/
Drupal.filterConfiguration.liveSettingParsers.filter_html = {
-
/**
* @return {Array}
* An array of filter rules.
*/
getRules() {
- const currentValue = $('#edit-filters-filter-html-settings-allowed-html').val();
- const rules = Drupal.behaviors.filterFilterHtmlUpdating._parseSetting(currentValue);
+ const currentValue = $(
+ '#edit-filters-filter-html-settings-allowed-html',
+ ).val();
+ const rules = Drupal.behaviors.filterFilterHtmlUpdating._parseSetting(
+ currentValue,
+ );
// Build a FilterHTMLRule that reflects the hard-coded behavior that
// strips all "style" attribute and all "on*" attributes.
@@ -44,7 +47,6 @@
* Attaches behavior for updating allowed HTML tags.
*/
Drupal.behaviors.filterFilterHtmlUpdating = {
-
// The form item contains the "Allowed HTML tags" setting.
$allowedHTMLFormItem: null,
@@ -66,35 +68,43 @@
attach(context, settings) {
const that = this;
- $(context).find('[name="filters[filter_html][settings][allowed_html]"]').once('filter-filter_html-updating').each(function () {
- that.$allowedHTMLFormItem = $(this);
- that.$allowedHTMLDescription = that.$allowedHTMLFormItem.closest('.js-form-item').find('.description');
- that.userTags = that._parseSetting(this.value);
+ $(context)
+ .find('[name="filters[filter_html][settings][allowed_html]"]')
+ .once('filter-filter_html-updating')
+ .each(function() {
+ that.$allowedHTMLFormItem = $(this);
+ that.$allowedHTMLDescription = that.$allowedHTMLFormItem
+ .closest('.js-form-item')
+ .find('.description');
+ that.userTags = that._parseSetting(this.value);
- // Update the new allowed tags based on added text editor features.
- $(document)
- .on('drupalEditorFeatureAdded', (e, feature) => {
- that.newFeatures[feature.name] = feature.rules;
- that._updateAllowedTags();
- })
- .on('drupalEditorFeatureModified', (e, feature) => {
- if (that.newFeatures.hasOwnProperty(feature.name)) {
+ // Update the new allowed tags based on added text editor features.
+ $(document)
+ .on('drupalEditorFeatureAdded', (e, feature) => {
that.newFeatures[feature.name] = feature.rules;
that._updateAllowedTags();
- }
- })
- .on('drupalEditorFeatureRemoved', (e, feature) => {
- if (that.newFeatures.hasOwnProperty(feature.name)) {
- delete that.newFeatures[feature.name];
- that._updateAllowedTags();
- }
- });
+ })
+ .on('drupalEditorFeatureModified', (e, feature) => {
+ if (that.newFeatures.hasOwnProperty(feature.name)) {
+ that.newFeatures[feature.name] = feature.rules;
+ that._updateAllowedTags();
+ }
+ })
+ .on('drupalEditorFeatureRemoved', (e, feature) => {
+ if (that.newFeatures.hasOwnProperty(feature.name)) {
+ delete that.newFeatures[feature.name];
+ that._updateAllowedTags();
+ }
+ });
- // When the allowed tags list is manually changed, update userTags.
- that.$allowedHTMLFormItem.on('change.updateUserTags', function () {
- that.userTags = _.difference(that._parseSetting(this.value), that.autoTags);
+ // When the allowed tags list is manually changed, update userTags.
+ that.$allowedHTMLFormItem.on('change.updateUserTags', function() {
+ that.userTags = _.difference(
+ that._parseSetting(this.value),
+ that.autoTags,
+ );
+ });
});
- });
},
/**
@@ -102,16 +112,28 @@
*/
_updateAllowedTags() {
// Update the list of auto-created tags.
- this.autoTags = this._calculateAutoAllowedTags(this.userTags, this.newFeatures);
+ this.autoTags = this._calculateAutoAllowedTags(
+ this.userTags,
+ this.newFeatures,
+ );
// Remove any previous auto-created tag message.
this.$allowedHTMLDescription.find('.editor-update-message').remove();
// If any auto-created tags: insert message and update form item.
if (!_.isEmpty(this.autoTags)) {
- this.$allowedHTMLDescription.append(Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags));
- const userTagsWithoutOverrides = _.omit(this.userTags, _.keys(this.autoTags));
- this.$allowedHTMLFormItem.val(`${this._generateSetting(userTagsWithoutOverrides)} ${this._generateSetting(this.autoTags)}`);
+ this.$allowedHTMLDescription.append(
+ Drupal.theme('filterFilterHTMLUpdateMessage', this.autoTags),
+ );
+ const userTagsWithoutOverrides = _.omit(
+ this.userTags,
+ _.keys(this.autoTags),
+ );
+ this.$allowedHTMLFormItem.val(
+ `${this._generateSetting(
+ userTagsWithoutOverrides,
+ )} ${this._generateSetting(this.autoTags)}`,
+ );
}
// Restore to original state.
else {
@@ -139,7 +161,7 @@
// Map the newly added Text Editor features to Drupal.FilterHtmlRule
// objects (to allow comparing userTags with autoTags).
- Object.keys(newFeatures || {}).forEach((featureName) => {
+ Object.keys(newFeatures || {}).forEach(featureName => {
const feature = newFeatures[featureName];
let featureRule;
let filterRule;
@@ -159,16 +181,26 @@
// always disallows the "style" attribute, so we only need to
// support "class" attribute value restrictions. Fix once
// https://www.drupal.org/node/2567801 lands.
- filterRule.restrictedTags.allowed.attributes = featureRule.required.attributes.slice(0);
- filterRule.restrictedTags.allowed.classes = featureRule.required.classes.slice(0);
+ filterRule.restrictedTags.allowed.attributes = featureRule.required.attributes.slice(
+ 0,
+ );
+ filterRule.restrictedTags.allowed.classes = featureRule.required.classes.slice(
+ 0,
+ );
editorRequiredTags[tag] = filterRule;
}
// The tag is already allowed, add any additionally allowed
// attributes.
else {
filterRule = editorRequiredTags[tag];
- filterRule.restrictedTags.allowed.attributes = _.union(filterRule.restrictedTags.allowed.attributes, featureRule.required.attributes);
- filterRule.restrictedTags.allowed.classes = _.union(filterRule.restrictedTags.allowed.classes, featureRule.required.classes);
+ filterRule.restrictedTags.allowed.attributes = _.union(
+ filterRule.restrictedTags.allowed.attributes,
+ featureRule.required.attributes,
+ );
+ filterRule.restrictedTags.allowed.classes = _.union(
+ filterRule.restrictedTags.allowed.classes,
+ featureRule.required.classes,
+ );
}
}
}
@@ -181,7 +213,7 @@
// - any tags in editorRequiredTags that already exists in userAllowedTags
// but does not allow all attributes or attribute values
const autoAllowedTags = {};
- Object.keys(editorRequiredTags).forEach((tag) => {
+ Object.keys(editorRequiredTags).forEach(tag => {
// If userAllowedTags does not contain a rule for this editor-required
// tag, then add it to the list of automatically allowed tags.
if (!_.has(userAllowedTags, tag)) {
@@ -191,20 +223,34 @@
// additional attributes and classes on this tag are required by the
// editor.
else {
- const requiredAttributes = editorRequiredTags[tag].restrictedTags.allowed.attributes;
- const allowedAttributes = userAllowedTags[tag].restrictedTags.allowed.attributes;
- const needsAdditionalAttributes = requiredAttributes.length && _.difference(requiredAttributes, allowedAttributes).length;
- const requiredClasses = editorRequiredTags[tag].restrictedTags.allowed.classes;
- const allowedClasses = userAllowedTags[tag].restrictedTags.allowed.classes;
- const needsAdditionalClasses = requiredClasses.length && _.difference(requiredClasses, allowedClasses).length;
+ const requiredAttributes =
+ editorRequiredTags[tag].restrictedTags.allowed.attributes;
+ const allowedAttributes =
+ userAllowedTags[tag].restrictedTags.allowed.attributes;
+ const needsAdditionalAttributes =
+ requiredAttributes.length &&
+ _.difference(requiredAttributes, allowedAttributes).length;
+ const requiredClasses =
+ editorRequiredTags[tag].restrictedTags.allowed.classes;
+ const allowedClasses =
+ userAllowedTags[tag].restrictedTags.allowed.classes;
+ const needsAdditionalClasses =
+ requiredClasses.length &&
+ _.difference(requiredClasses, allowedClasses).length;
if (needsAdditionalAttributes || needsAdditionalClasses) {
autoAllowedTags[tag] = userAllowedTags[tag].clone();
}
if (needsAdditionalAttributes) {
- autoAllowedTags[tag].restrictedTags.allowed.attributes = _.union(allowedAttributes, requiredAttributes);
+ autoAllowedTags[tag].restrictedTags.allowed.attributes = _.union(
+ allowedAttributes,
+ requiredAttributes,
+ );
}
if (needsAdditionalClasses) {
- autoAllowedTags[tag].restrictedTags.allowed.classes = _.union(allowedClasses, requiredClasses);
+ autoAllowedTags[tag].restrictedTags.allowed.classes = _.union(
+ allowedClasses,
+ requiredClasses,
+ );
}
}
});
@@ -255,8 +301,7 @@
if (attributeName === 'class') {
const attributeValue = attribute.textContent;
rule.restrictedTags.allowed.classes = attributeValue.split(' ');
- }
- else {
+ } else {
rule.restrictedTags.allowed.attributes.push(attributeName);
}
}
@@ -276,29 +321,34 @@
* The string representation of the setting. e.g. "<p> <br> <a>"
*/
_generateSetting(tags) {
- return _.reduce(tags, (setting, rule, tag) => {
- if (setting.length) {
- setting += ' ';
- }
+ return _.reduce(
+ tags,
+ (setting, rule, tag) => {
+ if (setting.length) {
+ setting += ' ';
+ }
- setting += `<${tag}`;
- if (rule.restrictedTags.allowed.attributes.length) {
- setting += ` ${rule.restrictedTags.allowed.attributes.join(' ')}`;
- }
- // @todo Drupal.FilterHtmlRule does not allow for generic attribute
- // value restrictions, only for the "class" and "style" attribute's
- // values. The filter_html filter always disallows the "style"
- // attribute, so we only need to support "class" attribute value
- // restrictions. Fix once https://www.drupal.org/node/2567801 lands.
- if (rule.restrictedTags.allowed.classes.length) {
- setting += ` class="${rule.restrictedTags.allowed.classes.join(' ')}"`;
- }
+ setting += `<${tag}`;
+ if (rule.restrictedTags.allowed.attributes.length) {
+ setting += ` ${rule.restrictedTags.allowed.attributes.join(' ')}`;
+ }
+ // @todo Drupal.FilterHtmlRule does not allow for generic attribute
+ // value restrictions, only for the "class" and "style" attribute's
+ // values. The filter_html filter always disallows the "style"
+ // attribute, so we only need to support "class" attribute value
+ // restrictions. Fix once https://www.drupal.org/node/2567801 lands.
+ if (rule.restrictedTags.allowed.classes.length) {
+ setting += ` class="${rule.restrictedTags.allowed.classes.join(
+ ' ',
+ )}"`;
+ }
- setting += '>';
- return setting;
- }, '');
+ setting += '>';
+ return setting;
+ },
+ '',
+ );
},
-
};
/**
@@ -310,12 +360,17 @@
* @return {string}
* The corresponding HTML.
*/
- Drupal.theme.filterFilterHTMLUpdateMessage = function (tags) {
+ Drupal.theme.filterFilterHTMLUpdateMessage = function(tags) {
let html = '';
- const tagList = Drupal.behaviors.filterFilterHtmlUpdating._generateSetting(tags);
+ const tagList = Drupal.behaviors.filterFilterHtmlUpdating._generateSetting(
+ tags,
+ );
html += '<p class="editor-update-message">';
- html += Drupal.t('Based on the text editor configuration, these tags have automatically been added: <strong>@tag-list</strong>.', { '@tag-list': tagList });
+ html += Drupal.t(
+ 'Based on the text editor configuration, these tags have automatically been added: <strong>@tag-list</strong>.',
+ { '@tag-list': tagList },
+ );
html += '</p>';
return html;
};
-}(jQuery, Drupal, _, document));
+})(jQuery, Drupal, _, document);
diff --git a/core/modules/history/js/history.es6.js b/core/modules/history/js/history.es6.js
index dba78b1..2cc5d66 100644
--- a/core/modules/history/js/history.es6.js
+++ b/core/modules/history/js/history.es6.js
@@ -5,13 +5,14 @@
* May only be loaded for authenticated users, with the History module enabled.
*/
-(function ($, Drupal, drupalSettings, storage) {
+(function($, Drupal, drupalSettings, storage) {
const currentUserID = parseInt(drupalSettings.user.uid, 10);
// Any comment that is older than 30 days is automatically considered read,
// so for these we don't need to perform a request at all!
const secondsIn30Days = 2592000;
- const thirtyDaysAgo = Math.round(new Date().getTime() / 1000) - secondsIn30Days;
+ const thirtyDaysAgo =
+ Math.round(new Date().getTime() / 1000) - secondsIn30Days;
// Use the data embedded in the page, if available.
let embeddedLastReadTimestamps = false;
@@ -23,7 +24,6 @@
* @namespace
*/
Drupal.history = {
-
/**
* Fetch "last read" timestamps for the given nodes.
*
@@ -45,8 +45,11 @@
data: { 'node_ids[]': nodeIDs },
dataType: 'json',
success(results) {
- Object.keys(results || {}).forEach((nodeID) => {
- storage.setItem(`Drupal.history.${currentUserID}.${nodeID}`, results[nodeID]);
+ Object.keys(results || {}).forEach(nodeID => {
+ storage.setItem(
+ `Drupal.history.${currentUserID}.${nodeID}`,
+ results[nodeID],
+ );
});
callback();
},
@@ -67,7 +70,10 @@
if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
return parseInt(embeddedLastReadTimestamps[nodeID], 10);
}
- return parseInt(storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0, 10);
+ return parseInt(
+ storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0,
+ 10,
+ );
},
/**
@@ -84,11 +90,17 @@
success(timestamp) {
// If the data is embedded in the page, don't store on the client
// side.
- if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
+ if (
+ embeddedLastReadTimestamps &&
+ embeddedLastReadTimestamps[nodeID]
+ ) {
return;
}
- storage.setItem(`Drupal.history.${currentUserID}.${nodeID}`, timestamp);
+ storage.setItem(
+ `Drupal.history.${currentUserID}.${nodeID}`,
+ timestamp,
+ );
},
});
},
@@ -119,11 +131,16 @@
// Use the data embedded in the page, if available.
if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
- return contentTimestamp > parseInt(embeddedLastReadTimestamps[nodeID], 10);
+ return (
+ contentTimestamp > parseInt(embeddedLastReadTimestamps[nodeID], 10)
+ );
}
- const minLastReadTimestamp = parseInt(storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0, 10);
+ const minLastReadTimestamp = parseInt(
+ storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0,
+ 10,
+ );
return contentTimestamp > minLastReadTimestamp;
},
};
-}(jQuery, Drupal, drupalSettings, window.localStorage));
+})(jQuery, Drupal, drupalSettings, window.localStorage);
diff --git a/core/modules/history/js/mark-as-read.es6.js b/core/modules/history/js/mark-as-read.es6.js
index 92d1d4a..38461b7 100644
--- a/core/modules/history/js/mark-as-read.es6.js
+++ b/