Commit 27881b60 authored by Benjamin Franzke's avatar Benjamin Franzke Committed by Benni Mack
Browse files

[TASK] Update bootstrap javascript to 5.0.0-beta1

Bootstrap v5 – introduced in #92616 – was added with CCS from beta1 but
JavaScript from alpha2. bootstrap.bundle.js was manually wrapped
into a AMD closure, and because bootstrap 5.0.0-beta1 contains alot of
changes regarding data tags, it couldn't be updated in the initial
patch.

Bootstrap is now bundled using rollup using the ES6 sources in order
to allow for automatic updates through `grunt build`.

popperjs – previously bundled into bootstrap distributed files –
is now added as dependency. The bootstap ES6 sources, that we now use
through rollup, do not bundle this external dependency (for good reasons).

Dependency added with:

   yarn add @popperjs/core

Further adaptions contained in this change to ensure beta1 compatibility:

a) Carousel "item" to "carousel-item" class migration
b) $.fn.modal(options) does no longer imply $.fn.modal('show')
c) Fix panels, both JS and CSS (card-group can't be used here)
d) All bootstrap data- tags are migrated to data-bs-.
   (see https://github.com/twbs/bootstrap/pull/31827)
   Migrated with

   # renderes a sed substition with the help of a nested sed from all the
   # data-bs attributes that where changed in the twbs/bootstrap commit
   git grep -l data- | xargs sed -i $( \
        curl -s \
        https://patch-diff.githubusercontent.com/raw/twbs/bootstrap/pull/31827.patch | \
        sed 's/data-bs-[a-z-]*/\n&\n/g' | grep "data-bs-[a-z-]" | \
        sort | uniq | \
        sed 's/data-bs-\(.*\)\([^a-z-]\|$\)/ -e s\/data-\1\\\([^a-z-]\\\)\/data-bs-\1\\1\/g -e s\/data('"'"'\1'"'"')\/data('"'"'bs-\1'"'"')\/g/g' \
   )

   # Revert false positives from the above auto-replacement
   git checkout -- typo3/sysext/core/Documentation/Changelog/ \
        typo3/sysext/backend/Classes/Form/Container/FlexFormContainerContainer.php \
        Build/Sources/TypeScript/backend/Resources/Public/TypeScript/LiveSearch.ts \
        Build/Sources/TypeScript/backend/Resources/Public/TypeScript/FormEngineFlexForm.ts \
        Build/Sources/TypeScript/install/Resources/Public/TypeScript/Module/Settings/ExtensionConfiguration.ts \
        Build/Sources/Sass/typo3/_element_panel.scss

   (cd Build && grunt build)

Resolves: #93126
Resolves: #93123
Resolves: #93132
Related: #92616
Releases: master
Change-Id: Ie194d0f87d2c60df7b9e8a6de4893cfaaea55356
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67215

Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: default avatarMartin Kutschker <mkutschker-typo3@yahoo.com>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: default avatarMartin Kutschker <mkutschker-typo3@yahoo.com>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 89f2e9f8
......@@ -82,7 +82,7 @@ class InstalledExtensionsCest
$I->switchToContentFrame();
$I->waitForElementVisible('//*[@id="typo3-extension-list"]/tbody/tr[@id="belog"]');
$I->click('a[data-original-title="Deactivate"]', '//*[@id="typo3-extension-list"]/tbody/tr[@id="belog"]');
$I->click('a[data-bs-original-title="Deactivate"]', '//*[@id="typo3-extension-list"]/tbody/tr[@id="belog"]');
$I->switchToMainFrame();
$I->cantSeeElement('#system_BelogLog');
......@@ -94,7 +94,7 @@ class InstalledExtensionsCest
$I->switchToContentFrame();
$I->waitForElementVisible('//*[@id="typo3-extension-list"]/tbody/tr[@id="belog"]');
$I->click('a[data-original-title="Activate"]', '//*[@id="typo3-extension-list"]/tbody/tr[@id="belog"]');
$I->click('a[data-bs-original-title="Activate"]', '//*[@id="typo3-extension-list"]/tbody/tr[@id="belog"]');
$I->switchToMainFrame();
$I->seeElement('#system_BelogLog');
......
......@@ -58,9 +58,9 @@ class CategoryTreeCest
$I->executeJS('$(\'.icon-actions-view-list-collapse\').click();');
$I->wait(1);
$I->executeJS('$(\'button[data-table="sys_category"] .icon-actions-view-list-expand\').click();');
$I->waitForElementVisible('#recordlist-sys_category tr[data-uid="7"] a[data-original-title="Edit record"]');
$I->waitForElementVisible('#recordlist-sys_category tr[data-uid="7"] a[data-bs-original-title="Edit record"]');
// Select category with id 7
$I->click('#recordlist-sys_category tr[data-uid="7"] a[data-original-title="Edit record"]');
$I->click('#recordlist-sys_category tr[data-uid="7"] a[data-bs-original-title="Edit record"]');
$I->waitForText('Category', 20);
// Change title and level to root
$I->fillField('input[data-formengine-input-name="data[sys_category][7][title]"]', 'level-1-4');
......
......@@ -43,7 +43,7 @@ class ElementsBasicInputDateCest extends AbstractElementsBasicCest
// Open record and wait until form is ready
$I->waitForText('elements basic', 20);
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForElementNotVisible('#t3js-ui-block');
......
......@@ -41,7 +41,7 @@ class ElementsBasicInputEvalCest extends AbstractElementsBasicCest
// Open record and wait until form is ready
$I->waitForText('elements basic', 20);
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForElementNotVisible('#t3js-ui-block');
$I->waitForText('Edit Form', 3, 'h1');
......
......@@ -41,7 +41,7 @@ class ElementsBasicInputRangeCest extends AbstractElementsBasicCest
// Open record and wait until form is ready
$I->waitForText('elements basic', 20);
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForElementNotVisible('#t3js-ui-block');
$I->waitForText('Edit Form', 3, 'h1');
......
......@@ -41,7 +41,7 @@ class ElementsBasicInputSimpleCest extends AbstractElementsBasicCest
// Open record and wait until form is ready
$I->waitForText('elements basic', 20);
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_basic a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForElementNotVisible('#t3js-ui-block');
$I->waitForText('Edit Form', 3, 'h1');
......
......@@ -42,7 +42,7 @@ class ElementsGroupCest
$I->executeJS('window.name="TYPO3Main";');
$I->waitForText('elements group', 20);
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_group a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_elements_group a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForText('Edit Form', 3, 'h1');
}
......
......@@ -44,7 +44,7 @@ class Inline1nCest
$I->switchToContentFrame();
$I->waitForText('inline 1n', 20);
$editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_1n a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_1n a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForText('Edit Form', 3, 'h1');
}
......@@ -55,12 +55,12 @@ class Inline1nCest
public function checkIfExpandsAndCollapseShowInput(BackendTester $I)
{
$I->wantTo('Expands the inline Element');
$I->click('div[data-toggle="formengine-inline"]', '[data-field-name^="[tx_styleguide_inline_1n_child]["]');
$I->click('div[data-bs-toggle="formengine-inline"]', '[data-field-name^="[tx_styleguide_inline_1n_child]["]');
$I->waitForElement('input[data-formengine-input-name="data[tx_styleguide_inline_1n_child][1][input_1]"]');
$I->wantTo('check is the value in input');
$I->seeInField('input[data-formengine-input-name="data[tx_styleguide_inline_1n_child][1][input_1]"]', 'lipsum');
$I->wantTo('Collapse the inline Element');
$I->click('div[data-toggle="formengine-inline"]', '[data-field-name^="[tx_styleguide_inline_1n_child]["]');
$I->click('div[data-bs-toggle="formengine-inline"]', '[data-field-name^="[tx_styleguide_inline_1n_child]["]');
$I->waitForElementNotVisible('[data-field-name^="[tx_styleguide_inline_1n_child]["] .panel');
}
......@@ -133,7 +133,7 @@ class Inline1nCest
*/
public function changeInline1nInlineInput(BackendTester $I)
{
$I->click('div[data-toggle="formengine-inline"]', '[data-field-name^="[tx_styleguide_inline_1n_child][1"]');
$I->click('div[data-bs-toggle="formengine-inline"]', '[data-field-name^="[tx_styleguide_inline_1n_child][1"]');
$I->waitForElement('input[data-formengine-input-name="data[tx_styleguide_inline_1n_child][1][input_1]"]');
$I->fillField('input[data-formengine-input-name="data[tx_styleguide_inline_1n_child][1][input_1]"]', 'hello world');
$I->click('button[name="_savedok"]');
......
......@@ -47,7 +47,7 @@ class NullPlaceholderCest
{
$I->amGoingTo('Check if deactivating null checkboxes marks as "changed"');
$editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[data-original-title="Edit record"]';
$editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[data-bs-original-title="Edit record"]';
$I->click($editRecordLinkCssPath);
$I->waitForElementNotVisible('#t3js-ui-block');
......
......@@ -62,7 +62,7 @@ class TasksCest
public function canRunTask(BackendTester $I)
{
// run the task
$I->click('a[data-original-title="Run task"]');
$I->click('a[data-bs-original-title="Run task"]');
$I->waitForText('Executed: System Status Update');
$I->seeElement('.tx_scheduler_mod1 .disabled');
$I->see('disabled');
......@@ -74,7 +74,7 @@ class TasksCest
*/
public function canEditTask(BackendTester $I)
{
$I->click('//a[contains(@data-original-title, "Edit")]');
$I->click('//a[contains(@data-bs-original-title, "Edit")]');
$I->waitForText('Edit task');
$I->seeInField('#task_SystemStatusUpdateNotificationEmail', 'test@local.typo3.org');
$I->fillField('#task_SystemStatusUpdateNotificationEmail', 'foo@local.typo3.org');
......@@ -91,11 +91,11 @@ class TasksCest
public function canEnableAndDisableTask(BackendTester $I)
{
$I->wantTo('See a enable button for a task');
$I->click('//a[contains(@data-original-title, "Enable")]', '#tx_scheduler_form');
$I->click('//a[contains(@data-bs-original-title, "Enable")]', '#tx_scheduler_form');
$I->dontSeeElement('.tx_scheduler_mod1 .disabled');
$I->dontSee('disabled');
$I->wantTo('See a disable button for a task');
$I->click('//a[contains(@data-original-title, "Disable")]');
$I->click('//a[contains(@data-bs-original-title, "Disable")]');
$I->waitForElementVisible('div.tx_scheduler_mod1');
$I->seeElement('.tx_scheduler_mod1 .disabled');
$I->see('disabled');
......@@ -109,8 +109,8 @@ class TasksCest
public function canDeleteTask(BackendTester $I, ModalDialog $modalDialog)
{
$I->wantTo('See a delete button for a task');
$I->seeElement('//a[contains(@data-original-title, "Delete")]');
$I->click('//a[contains(@data-original-title, "Delete")]');
$I->seeElement('//a[contains(@data-bs-original-title, "Delete")]');
$I->click('//a[contains(@data-bs-original-title, "Delete")]');
$I->wantTo('Cancel the delete dialog');
// don't use $modalDialog->clickButtonInDialog due to too low timeout
......@@ -120,7 +120,7 @@ class TasksCest
$I->switchToContentFrame();
$I->wantTo('Still see and can click the Delete button as the deletion has been canceled');
$I->click('//a[contains(@data-original-title, "Delete")]');
$I->click('//a[contains(@data-bs-original-title, "Delete")]');
$modalDialog->clickButtonInDialog('OK');
$I->switchToContentFrame();
$I->see('The task was successfully deleted.');
......
......@@ -78,7 +78,7 @@
<f:for each="{widgetGroups}" as="groupConfiguration" iteration="iterator">
<f:if condition="{groupConfiguration.widgets}">
<li class="t3js-tabmenu-item nav-item">
<a id="dashboard-widgetgroup-tab-{groupConfiguration.identifier}" class="nav-link {f:if(condition: '{firstGroupActive} == \'false\'', then: 'active')}" data-toggle="tab" href="#dashboard-widgetgroup-{groupConfiguration.identifier}" role="tab" aria-controls="dashboard-widgetgroup-{groupConfiguration.identifier}" aria-selected="true">{groupConfiguration.title}</a>
<a id="dashboard-widgetgroup-tab-{groupConfiguration.identifier}" class="nav-link {f:if(condition: '{firstGroupActive} == \'false\'', then: 'active')}" data-bs-toggle="tab" href="#dashboard-widgetgroup-{groupConfiguration.identifier}" role="tab" aria-controls="dashboard-widgetgroup-{groupConfiguration.identifier}" aria-selected="true">{groupConfiguration.title}</a>
</li>
<f:variable name="firstGroupActive" value="true" />
</f:if>
......
......@@ -246,7 +246,7 @@ class FileList
if ($warning) {
$attributes['class'] = 'btn btn-default t3js-modal-trigger';
$attributes['data-severity'] = 'warning';
$attributes['data-content'] = $warning;
$attributes['data-bs-content'] = $warning;
$attributes['data-event-name'] = 'filelist:clipboard:cmd';
$attributes['data-event-payload'] = $cmd;
} else {
......@@ -375,7 +375,7 @@ class FileList
'_FILE',
$this->folderObject->getCombinedIdentifier()
)) . '"'
. ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText(
. ' data-bs-content="' . htmlspecialchars($this->clipObj->confirmMsgText(
'_FILE',
$this->folderObject->getReadablePath(),
'into',
......@@ -976,7 +976,7 @@ class FileList
if ($addPasteButton) {
$cells[] = '<a class="btn btn-default t3js-modal-trigger" '
. ' href="' . htmlspecialchars($this->clipObj->pasteUrl('_FILE', $fullIdentifier)) . '"'
. ' data-content="' . htmlspecialchars($this->clipObj->confirmMsgText('_FILE', $fullName, 'into', $elToConfirm)) . '"'
. ' data-bs-content="' . htmlspecialchars($this->clipObj->confirmMsgText('_FILE', $fullName, 'into', $elToConfirm)) . '"'
. ' data-severity="warning"'
. ' data-title="' . htmlspecialchars($this->getLanguageService()->getLL('clip_pasteInto')) . '"'
. ' title="' . htmlspecialchars($this->getLanguageService()->getLL('clip_pasteInto')) . '"'
......@@ -1108,7 +1108,7 @@ class FileList
$deleteUrl = (string)$this->uriBuilder->buildUriFromRoute('tce_file');
$confirmationMessage = sprintf($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.delete'), $fileOrFolderObject->getName()) . $referenceCountText;
$title = $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete');
$cells['delete'] = '<a href="#" class="btn btn-default t3js-filelist-delete" data-content="' . htmlspecialchars($confirmationMessage)
$cells['delete'] = '<a href="#" class="btn btn-default t3js-filelist-delete" data-bs-content="' . htmlspecialchars($confirmationMessage)
. '" data-check="' . $confirmationCheck
. '" data-delete-url="' . htmlspecialchars($deleteUrl)
. '" data-title="' . htmlspecialchars($title)
......
......@@ -184,7 +184,7 @@
title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete' )}"
data-identifier="{file.identifier}"
data-title="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.delete' )}"
data-content="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.delete', arguments: '{0:file.name}' )}"
data-bs-content="{f:translate( key:'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:mess.delete', arguments: '{0:file.name}' )}"
data-check="{f:if(condition:settings.jsConfirmationDelete, then:'1', else:'0')}"
data-delete-url="{deleteUrl}"
data-delete-type="delete_file"
......
......@@ -352,13 +352,13 @@ class TypolinkViewHelperTest extends FunctionalTestCase
[
'parameter' => 'http://typo3.org/ "_self" "<CSS>" "<Title>"',
'additionalAttributes' => [
'data-html' => '<div data-template="template">'
'data-bs-html' => '<div data-template="template">'
. '<img src="logo.png" alt="&quot;&lt;ALT&gt;&quot;"></div>',
'data-other' => '\'\'',
],
],
'<a href="http://typo3.org/" title="&lt;Title&gt;" target="_self"'
. ' class="&lt;CSS&gt;" data-html="&lt;div data-template=&quot;template&quot;&gt;'
. ' class="&lt;CSS&gt;" data-bs-html="&lt;div data-template=&quot;template&quot;&gt;'
. '&lt;img src=&quot;logo.png&quot; alt=&quot;&amp;quot;&amp;lt;ALT&amp;gt;&amp;quot;&quot;&gt;&lt;/div&gt;"'
. ' data-other="\'\'">Link Text</a>'
]
......
......@@ -8,7 +8,7 @@
</div>
<span class="input-group-btn" role="group" data-identifier="inspectorEditorFormElementSelectorControlsWrapper">
<span class="btn-group t3-form-dropdown-buttons" data-identifier="inspectorEditorFormElementSelectorSplitButtonContainer">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.inspector.editor.formelement_selector.title')}">
<button type="button" class="btn btn-default dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.inspector.editor.formelement_selector.title')}">
<core:icon identifier="actions-variable-select" />
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
......
......@@ -6,7 +6,7 @@
</div>
<div class="btn-group btn-group-sm" role="group">
<div class="btn-group t3-form-dropdown-buttons" data-identifier="stageElementToolbarNewElementSplitButton">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element')}">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element')}">
<core:icon identifier="actions-document-new" alternativeMarkupIdentifier="inline" />
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
......
......@@ -35,17 +35,17 @@
<td class="col-icon nowrap">
<f:if condition="{form.invalid}">
<f:then>
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.invalid')}" data-toggle="tooltip" data-placement="top">
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.invalid')}" data-bs-toggle="tooltip" data-bs-placement="top">
<core:icon identifier="overlay-missing" />
</span>
</f:then>
<f:else if="{form.duplicateIdentifier}">
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.duplicate_identifier')} {form.identifier}" data-toggle="tooltip" data-placement="top">
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.duplicate_identifier')} {form.identifier}" data-bs-toggle="tooltip" data-bs-placement="top">
<core:icon identifier="overlay-missing" />
</span>
</f:else>
<f:else>
<span title="id={form.identifier}" data-toggle="tooltip" data-placement="right">
<span title="id={form.identifier}" data-bs-toggle="tooltip" data-bs-placement="right">
<core:icon identifier="content-form" />
</span>
</f:else>
......
......@@ -1172,7 +1172,7 @@ define(['jquery',
var iconWrap;
iconWrap = $('<a></a>')
.attr('href', _getCollectionElementId(collectionName, collectionElementIdentifier, true))
.attr('data-toggle', 'collapse')
.attr('data-bs-toggle', 'collapse')
.attr('aria-expanded', 'true')
.attr('aria-controls', _getCollectionElementId(collectionName, collectionElementIdentifier))
.addClass('collapsed')
......
......@@ -62,7 +62,7 @@ define(['jquery',
showReferences: {identifier: '[data-identifier="showReferences"]'},
referenceLink: {identifier: '[data-identifier="referenceLink"]'},
tooltip: {identifier: '[data-toggle="tooltip"]'},
tooltip: {identifier: '[data-bs-toggle="tooltip"]'},
moduleBody: {class: '.module-body.t3js-module-body'},
t3Logo: {class: '.t3-message-page-logo'},
......
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