Issue #3276213 by nod_, Wim Leers, lauriii, mherchel, longwave: Uncaught exception when data-caption contains markup upcasting to a model element

(cherry picked from commit afc43ea00f)
merge-requests/2973/head
Alex Pott 2022-11-16 11:39:58 +00:00
parent dbaa5e8744
commit c62e7d1c80
No known key found for this signature in database
GPG Key ID: BDA67E7EE836E5CE
6 changed files with 28 additions and 23 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -478,20 +478,13 @@ function viewImageToModelImage(editor) {
const viewFragment = editor.data.processor.toView(
viewItem.getAttribute('data-caption'),
);
const modelFragment = writer.createDocumentFragment();
// Consumable must know about those newly parsed view elements.
conversionApi.consumable.constructor.createFrom(
viewFragment,
conversionApi.consumable,
);
conversionApi.convertChildren(viewFragment, modelFragment);
// Insert caption model nodes into the caption.
// eslint-disable-next-line no-restricted-syntax
for (const child of Array.from(modelFragment.getChildren())) {
writer.append(child, caption);
}
conversionApi.convertChildren(viewFragment, caption);
// Insert the caption element into image, as a last child.
writer.append(caption, image);

View File

@ -36,20 +36,13 @@ function viewToModelCaption(editor) {
const viewFragment = editor.data.processor.toView(
viewItem.getAttribute('data-caption'),
);
const modelFragment = writer.createDocumentFragment();
// Consumable must know about those newly parsed view elements.
conversionApi.consumable.constructor.createFrom(
viewFragment,
conversionApi.consumable,
);
conversionApi.convertChildren(viewFragment, modelFragment);
// Insert caption model nodes into the caption.
// eslint-disable-next-line no-restricted-syntax
for (const child of Array.from(modelFragment.getChildren())) {
writer.append(child, caption);
}
conversionApi.convertChildren(viewFragment, caption);
// Insert the caption element into drupalMedia, as a last child.
writer.append(caption, drupalMedia);

View File

@ -574,7 +574,7 @@ abstract class ImageTestBase extends CKEditor5TestBase {
// The foo attribute is added to be removed later by CKEditor 5 to make sure
// CKEditor 5 was able to downcast data.
$img_tag = '<img ' . $this->imageAttributesAsString() . ' alt="drupalimage test image" data-caption="Alpacas &lt;em&gt;are&lt;/em&gt; cute" foo="bar">';
$img_tag = '<img ' . $this->imageAttributesAsString() . ' alt="drupalimage test image" data-caption="Alpacas &lt;em&gt;are&lt;/em&gt; cute&lt;br&gt;really!" foo="bar">';
$this->host->body->value = $img_tag;
$this->host->save();
@ -583,18 +583,18 @@ abstract class ImageTestBase extends CKEditor5TestBase {
$this->assertNotEmpty($assert_session->waitForElement('css', '.ck-editor'));
$this->assertNotEmpty($figcaption = $assert_session->waitForElement('css', '.image figcaption'));
$this->assertSame('Alpacas <em>are</em> cute', $figcaption->getHtml());
$this->assertSame('Alpacas <em>are</em> cute<br>really!', $figcaption->getHtml());
$page->pressButton('Source');
$editor_dom = $this->getEditorDataAsDom();
$data_caption = $editor_dom->getElementsByTagName('img')->item(0)->getAttribute('data-caption');
$this->assertSame('Alpacas <em>are</em> cute', $data_caption);
$this->assertSame('Alpacas <em>are</em> cute<br>really!', $data_caption);
$page->pressButton('Save');
$src = $this->imageAttributes()['src'];
$this->assertEquals('<img ' . $this->imageAttributesAsString(TRUE) . ' alt="drupalimage test image" data-caption="Alpacas &lt;em&gt;are&lt;/em&gt; cute">', Node::load(1)->get('body')->value);
$this->assertEquals('<img ' . $this->imageAttributesAsString(TRUE) . ' alt="drupalimage test image" data-caption="Alpacas &lt;em&gt;are&lt;/em&gt; cute&lt;br&gt;really!">', Node::load(1)->get('body')->value);
$assert_session->elementExists('xpath', '//figure/img[@src="' . $src . '" and not(@data-caption)]');
$assert_session->responseContains('<figcaption>Alpacas <em>are</em> cute</figcaption>');
$assert_session->responseContains('<figcaption>Alpacas <em>are</em> cute<br>really!</figcaption>');
}
/**

View File

@ -614,6 +614,25 @@ class MediaTest extends WebDriverTestBase {
$editor_dom = $this->getEditorDataAsDom();
$this->assertEquals('Llamas are the most awesome ever', $editor_dom->getElementsByTagName('drupal-media')->item(0)->getAttribute('data-caption'));
// Ensure that caption can contain elements such as <br>.
$this->pressEditorButton('Source');
$source_text_area = $assert_session->waitForElement('css', '.ck-source-editing-area textarea');
$source_text = $source_text_area->getValue();
$source_text_area->setValue(str_replace('data-caption="Llamas are the most awesome ever"', 'data-caption="Llamas are the most<br>awesome ever"', $source_text));
// Click source again to make source inactive.
$this->pressEditorButton('Source');
// Check that the source mode is toggled off.
$assert_session->elementNotExists('css', '.ck-source-editing-area textarea');
// Put back the caption as it was before.
$this->pressEditorButton('Source');
$source_text_area = $assert_session->waitForElement('css', '.ck-source-editing-area textarea');
$source_text = $source_text_area->getValue();
$source_text_area->setValue(str_replace('data-caption="Llamas are the most&lt;br&gt;awesome ever"', 'data-caption="Llamas are the most awesome ever"', $source_text));
// Click source again to make source inactive.
$this->pressEditorButton('Source');
// Check that the source mode is toggled off.
$assert_session->elementNotExists('css', '.ck-source-editing-area textarea');
// Ensure that caption can be linked.
$this->assertNotEmpty($figcaption = $assert_session->waitForElement('css', '.drupal-media figcaption'));
$this->selectTextInsideElement('.drupal-media figcaption');