Unverified Commit 213a5659 authored by lauriii's avatar lauriii
Browse files

Issue #3207782 by nod_, bnjmnm, jptaranto: Add BC layer between @drupal/once and jQuery.once

parent 167686b8
......@@ -528,6 +528,16 @@ jquery.once:
assets/vendor/jquery-once/jquery.once.min.js: { weight: -19, minified: true }
dependencies:
- core/jquery
- core/jquery.once.bc
jquery.once.bc:
version: VERSION
js:
misc/jquery.once.bc.js: { weight: -19 }
dependencies:
- core/jquery
- core/once
- core/drupal.object.assign
jquery.ui:
version: &jquery_ui_version 1.12.1
......
/**
* @file
* This file allows calls to `once()` and `once.remove()` to also populate the
* jQuery.once registry.
*
* It allows contributed code still using jQuery.once to behave as expected:
* @example
* once('core-once-call', 'body');
*
* // The following will work in a contrib module still using jQuery.once:
* $('body').once('core-once-call'); // => returns empty object
*/
(($, once) => {
// We'll replace the whole library so keep a version in cache for later.
const drupalOnce = once;
// When calling once(), also populate jQuery.once registry.
function augmentedOnce(id, selector, context) {
$(selector, context).once(id);
return drupalOnce(id, selector, context);
}
// When calling once.remove(), also remove it from jQuery.once registry.
function remove(id, selector, context) {
$(selector, context).removeOnce(id);
return drupalOnce.remove(id, selector, context);
}
// Expose the rest of @drupal/once API and replace @drupal/once library with
// the version augmented with jQuery.once calls.
window.once = Object.assign(augmentedOnce, drupalOnce, { remove });
})(jQuery, once);
/**
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
(function ($, once) {
var drupalOnce = once;
function augmentedOnce(id, selector, context) {
$(selector, context).once(id);
return drupalOnce(id, selector, context);
}
function remove(id, selector, context) {
$(selector, context).removeOnce(id);
return drupalOnce.remove(id, selector, context);
}
window.once = Object.assign(augmentedOnce, drupalOnce, {
remove: remove
});
})(jQuery, once);
\ No newline at end of file
name: 'JS once Test'
type: module
description: 'Module for the jsOnceTest.'
package: Testing
version: VERSION
js_once_test:
path: '/js_once_test'
defaults:
_controller: '\Drupal\js_once_test\Controller\JsOnceTestController::onceTest'
_title: 'OnceTest'
requirements:
_access: 'TRUE'
js_once_test.with_bc:
path: '/js_once_with_bc_test'
defaults:
_controller: '\Drupal\js_once_test\Controller\JsOnceTestController::onceBcTest'
_title: 'OnceBcTest'
requirements:
_access: 'TRUE'
<?php
namespace Drupal\js_once_test\Controller;
use Drupal\Core\Controller\ControllerBase;
/**
* Controller for testing the @drupal/once library integration.
*/
class JsOnceTestController extends ControllerBase {
/**
* Provides elements for testing @drupal/once.
*
* @return array
* The render array.
*/
public function onceTest() {
$output = [
'#attached' => ['library' => ['core/once']],
];
foreach (range(1, 5) as $item) {
$output['item' . $item] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => 'Item ' . $item,
'#attributes' => [
'data-drupal-item' => $item,
],
];
}
return $output;
}
/**
* Provides elements for testing jQuery Once BC support.
*
* @return array
* The render array.
*/
public function onceBcTest() {
$output = [
'#attached' => ['library' => ['core/jquery.once']],
];
foreach (range(1, 5) as $item) {
$output['item' . $item] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => 'Item ' . $item,
'#attributes' => [
'data-drupal-item' => $item,
],
];
}
return $output;
}
}
module.exports = {
'@tags': ['core'],
before(browser) {
browser.drupalInstall().drupalLoginAsAdmin(() => {
browser
.drupalRelativeURL('/admin/modules')
.setValue('input[type="search"]', 'JS Once Test')
.waitForElementVisible(
'input[name="modules[js_once_test][enable]"]',
1000,
)
.click('input[name="modules[js_once_test][enable]"]')
.click('input[type="submit"]'); // Submit module form.
});
},
after(browser) {
browser.drupalUninstall();
},
'Test simple once call': (browser) => {
browser
.drupalRelativeURL('/js_once_test')
.waitForElementVisible('[data-drupal-item]', 1000)
// prettier-ignore
.execute(
function () {
return once('js_once_test', '[data-drupal-item]');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
5,
'5 items returned and "once-d"',
);
},
)
// Check that follow-up calls to once return an empty array.
.execute(
function () {
return once('js_once_test', '[data-drupal-item]');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
0,
'0 items returned',
);
},
)
.execute(
function () {
return once(
'js_once_test_extra',
'[data-drupal-item="1"],[data-drupal-item="2"]',
);
},
(result) => {
browser.assert.strictEqual(
result.value.length,
2,
'2 items returned and "once-d"',
);
},
)
.execute(
function () {
return once(
'js_once_test_extra',
'[data-drupal-item="1"],[data-drupal-item="2"]',
);
},
(result) => {
browser.assert.strictEqual(
result.value.length,
0,
'0 items returned',
);
},
)
.execute(
function () {
return once.remove('js_once_test', '[data-drupal-item]');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
5,
'5 items returned and "de-once-d"',
);
},
)
.execute(
function () {
return once.remove('js_once_test', '[data-drupal-item]');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
0,
'0 items returned',
);
},
)
.execute(
function () {
return once.remove(
'js_once_test_extra',
'[data-drupal-item="1"],[data-drupal-item="2"]',
);
},
(result) => {
browser.assert.strictEqual(
result.value.length,
2,
'2 items returned and "de-once-d"',
);
},
)
.execute(
function () {
return once.remove(
'js_once_test_extra',
'[data-drupal-item="1"],[data-drupal-item="2"]',
);
},
(result) => {
browser.assert.strictEqual(
result.value.length,
0,
'0 items returned',
);
},
)
.drupalLogAndEnd({ onlyOnError: false });
},
'Test BC layer with jQuery Once calls': (browser) => {
browser
.drupalRelativeURL('/js_once_with_bc_test')
.waitForElementVisible('[data-drupal-item]', 1000)
// prettier-ignore
.execute(
function () {
// A core script calls once on some elements.
once('js_once_test', '[data-drupal-item]');
// A contrib module not yet using @drupal/once calls jQuery Once.
return jQuery('[data-drupal-item]').once('js_once_test');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
0,
'Calls to once() are taken into account when using jQuery.once()',
);
},
)
// Once calls don't take into account calls to jQuery.once by design.
.execute(
function () {
// Calling jQuery.once before @drupal/once will lead to duplicate
// processing.
jQuery('[data-drupal-item]').once('js_once_test_extra');
// A core script calls once on some elements.
return once('js_once_test_extra', '[data-drupal-item]');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
5,
'5 items returned by once() after a call to jQuery.once()',
);
},
)
.execute(
function () {
once('js_once_test_remove', '[data-drupal-item]');
// A core script calls once on some elements.
once.remove('js_once_test_remove', '[data-drupal-item]');
// A contrib module not yet using @drupal/once calls the jQuery Once
// remove() function.
return jQuery('[data-drupal-item]').removeOnce('js_once_test_remove');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
0,
'Calls to once.remove() are taken into account when using jQuery.removeOnce()',
);
},
)
// Once.remove calls don't take into account calls to jQuery.removeOnce by
// design.
.execute(
function () {
once('js_once_test_remove_fail', '[data-drupal-item]');
// Calling jQuery.removeOnce before @drupal/once will lead to
// duplicate processing.
jQuery('[data-drupal-item]').removeOnce('js_once_test_remove_fail');
// A core script calls once.remove on some elements.
return once.remove('js_once_test_remove_fail', '[data-drupal-item]');
},
(result) => {
browser.assert.strictEqual(
result.value.length,
5,
'5 items returned by once.remove() after a call to jQuery.removeOnce()',
);
},
)
.drupalLogAndEnd({ onlyOnError: false });
},
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment