Issue #3241295 by mherchel, glynster, _utsavsharma, Emil Stoianov, rkoller, Wim Leers, gaurav-mathur, DeepaliJ, geek-merlin, tgoeg, ckrina, mgifford, zcht, Dom., smustgrave, nod_, mstrelan, RgnYLDZ: CKEditor 5 isn't respecting field widgets row settings

merge-requests/2928/merge
Lauri Eskola 2022-12-29 16:29:43 +02:00
parent 0498fbfc68
commit eddae13734
No known key found for this signature in database
GPG Key ID: 382FC0F5B0DF53F8
5 changed files with 234 additions and 1 deletions

View File

@ -1101,6 +1101,7 @@ someschema
somethinggeneric
sortablejs
sourcedir
sourceediting
spacebar
spagna
specialchars

View File

@ -8,3 +8,14 @@
opacity: 1 !important;
fill-opacity: 1 !important;
}
/**
* Set the min-height equal to configuration value for the number of rows.
*
* The `--ck-min-height` value is set on the parent `.ck-editor` element by
* JavaScript. We add that there because the `.ck-editor__editable` element's
* inline styles are cleared on focus.
*/
.ck-editor__main > :is(.ck-editor__editable, .ck-source-editing-area) {
min-height: var(--ck-min-height);
}

View File

@ -370,9 +370,55 @@
ClassicEditor.create(element, editorConfig)
.then((editor) => {
/**
* Injects a temporary <p> into CKEditor and then calculates the entire
* height of the amount of the <p> tags from the passed in rows value.
*
* This takes into account collapsing margins, and line-height of the
* current theme.
*
* @param {number} - the number of rows.
*
* @returns {number} - the height of a div in pixels.
*/
function calculateLineHeight(rows) {
const element = document.createElement('p');
element.setAttribute('style', 'visibility: hidden;');
element.innerHTML = '&nbsp;';
editor.ui.view.editable.element.append(element);
const styles = window.getComputedStyle(element);
const height = element.clientHeight;
const marginTop = parseInt(styles.marginTop, 10);
const marginBottom = parseInt(styles.marginBottom, 10);
const mostMargin =
marginTop >= marginBottom ? marginTop : marginBottom;
element.remove();
return (
(height + mostMargin) * (rows - 1) +
marginTop +
height +
marginBottom
);
}
// Save a reference to the initialized instance.
Drupal.CKEditor5Instances.set(id, editor);
// Set the minimum height of the editable area to correspond with the
// value of the number of rows. We attach this custom property to
// the `.ck-editor` element, as that doesn't get its inline styles
// cleared on focus. The editable element is then set to use this
// property within the stylesheet.
const rows = editor.sourceElement.getAttribute('rows');
editor.ui.view.editable.element
.closest('.ck-editor')
.style.setProperty(
'--ck-min-height',
`${calculateLineHeight(rows)}px`,
);
// CKEditor 4 had a feature to remove the required attribute
// see: https://www.drupal.org/project/drupal/issues/1954968
if (element.hasAttribute('required')) {

View File

@ -0,0 +1,175 @@
module.exports = {
'@tags': ['core', 'ckeditor5'],
before(browser) {
browser.drupalInstall({ installProfile: 'minimal' });
},
after(browser) {
browser.drupalUninstall();
},
'Ensure CKEditor respects field widget row value': (browser) => {
browser.drupalLoginAsAdmin(() => {
browser
// Enable required modules.
.drupalRelativeURL('/admin/modules')
.click('[name="modules[ckeditor5][enable]"]')
.click('[name="modules[field_ui][enable]"]')
.submitForm('input[type="submit"]') // Submit module form.
.waitForElementVisible(
'.system-modules-confirm-form input[value="Continue"]',
)
.submitForm('input[value="Continue"]') // Confirm installation of dependencies.
.waitForElementVisible('.system-modules', 10000)
// Create new input format.
.drupalRelativeURL('/admin/config/content/formats/add')
.waitForElementVisible('[data-drupal-selector="edit-name"]')
.updateValue('[data-drupal-selector="edit-name"]', 'test')
.waitForElementVisible('#edit-name-machine-name-suffix')
.click(
'[data-drupal-selector="edit-editor-editor"] option[value=ckeditor5]',
)
// Wait for CKEditor 5 settings to be visible.
.waitForElementVisible(
'[data-drupal-selector="edit-editor-settings-toolbar"]',
)
.click('.ckeditor5-toolbar-button-sourceEditing') // Select the Source Editing button.
.keys(browser.Keys.DOWN) // Hit the down arrow key to move it to the toolbar.
// Wait for new source editing vertical tab to be present before continuing.
.waitForElementVisible(
'[href*=edit-editor-settings-plugins-ckeditor5-sourceediting]',
)
.submitForm('input[type="submit"]')
.waitForElementVisible('[data-drupal-messages]')
.assert.textContains('[data-drupal-messages]', 'Added text format')
// Create new content type.
.drupalRelativeURL('/admin/structure/types/add')
.waitForElementVisible('[data-drupal-selector="edit-name"]')
.updateValue('[data-drupal-selector="edit-name"]', 'test')
.waitForElementVisible('#edit-name-machine-name-suffix') // Wait for machine name to update.
.submitForm('input[type="submit"]')
.waitForElementVisible('[data-drupal-messages]')
.assert.textContains(
'[data-drupal-messages]',
'The content type test has been added',
)
// Navigate to the create content page and measure height of the editor.
.drupalRelativeURL('/node/add/test')
.waitForElementVisible('.ck-editor__editable')
.execute(
// eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
function () {
const height = document.querySelector(
'.ck-editor__editable',
).clientHeight;
// We expect height to be 320, but test to ensure that it's greater
// than 300. We want to ensure that we don't hard code a very specific
// value because tests might break if styles change (line-height, etc).
// Note that the default height for CKEditor5 is 47px.
return height > 300;
},
[],
(result) => {
browser.assert.ok(
result.value,
'Editor height is set to 9 rows (default).',
);
},
)
.click('.ck-source-editing-button')
.waitForElementVisible('.ck-source-editing-area')
.execute(
// eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
function () {
const height = document.querySelector(
'.ck-source-editing-area',
).clientHeight;
// We expect height to be 320, but test to ensure that it's greater
// than 300. We want to ensure that we don't hard code a very specific
// value because tests might break if styles change (line-height, etc).
// Note that the default height for CKEditor5 is 47px.
return height > 300;
},
[],
(result) => {
browser.assert.ok(
result.value,
'Source editing height is set to 9 rows (default).',
);
},
)
// Double the editor row count.
.drupalRelativeURL('/admin/structure/types/manage/test/form-display')
.waitForElementVisible(
'[data-drupal-selector="edit-fields-body-settings-edit"]',
)
.click('[data-drupal-selector="edit-fields-body-settings-edit"]')
.waitForElementVisible(
'[data-drupal-selector="edit-fields-body-settings-edit-form-settings-rows"]',
)
.updateValue(
'[data-drupal-selector="edit-fields-body-settings-edit-form-settings-rows"]',
'18',
)
// Save field settings.
.click(
'[data-drupal-selector="edit-fields-body-settings-edit-form-actions-save-settings"]',
)
.waitForElementVisible(
'[data-drupal-selector="edit-fields-body"] .field-plugin-summary',
)
.click('[data-drupal-selector="edit-submit"]')
.waitForElementVisible('[data-drupal-messages]')
.assert.textContains(
'[data-drupal-messages]',
'Your settings have been saved',
)
// Navigate to the create content page and measure height of the editor.
.drupalRelativeURL('/node/add/test')
.execute(
// eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
function () {
const height = document.querySelector(
'.ck-editor__editable',
).clientHeight;
// We expect height to be 640, but test to ensure that it's greater
// than 600. We want to ensure that we don't hard code a very specific
// value because tests might break if styles change (line-height, etc).
// Note that the default height for CKEditor5 is 47px.
return height > 600;
},
[],
(result) => {
browser.assert.ok(result.value, 'Editor height is set to 18 rows.');
},
)
.click('.ck-source-editing-button')
.waitForElementVisible('.ck-source-editing-area')
.execute(
// eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
function () {
const height = document.querySelector(
'.ck-source-editing-area',
).clientHeight;
// We expect height to be 640, but test to ensure that it's greater
// than 600. We want to ensure that we don't hard code a very specific
// value because tests might break if styles change (line-height, etc).
// Note that the default height for CKEditor5 is 47px.
return height > 600;
},
[],
(result) => {
browser.assert.ok(
result.value,
'Source editing height is set to 18 rows (default).',
);
},
);
});
},
};

View File

@ -25,7 +25,7 @@ class TextareaWidget extends StringTextareaWidget {
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element = parent::settingsForm($form, $form_state);
$element['rows']['#description'] = $this->t('Text editors (like CKEditor) may override this setting.');
$element['rows']['#description'] = $this->t('Text editors may override this setting.');
return $element;
}