Skip to content
Snippets Groups Projects
Commit 2924e677 authored by Marius Dumitru Florea's avatar Marius Dumitru Florea
Browse files

XWIKI-22482: Links wrapping images that have been centered with the old image...

XWIKI-22482: Links wrapping images that have been centered with the old image dialog are lost on save
* Fix the image widget initialization and downcast when the image was previously inserted with the old image dialog.
parent 41c7ff80
No related branches found
No related tags found
No related merge requests found
...@@ -446,22 +446,39 @@ ...@@ -446,22 +446,39 @@
widget.on('data', function () { widget.on('data', function () {
widget.resizer[widget.data.alignment === 'end' ? 'addClass' : 'removeClass']('cke_image_resizer_left'); widget.resizer[widget.data.alignment === 'end' ? 'addClass' : 'removeClass']('cke_image_resizer_left');
}); });
if(!widget.wrapper.getChild(0).hasClass('cke_widget_element')) { // The image has been wrapped in the image resize wrapper. If the image was the widget element then we need to
// Re-wrap the element in a widget element. // create another widget element to hold the image resize wrapper (which includes the image).
// This happens when removing the caption of an image. if (!widget.wrapper.getChild(0).hasClass('cke_widget_element')) {
var widgetElement = editor.document.createElement('span'); const oldWidgetElement = widget.element;
widgetElement.addClass('cke_widget_element'); const widgetElementAttrs = [
if (resizeWrapper) { 'data-cke-widget-data',
widgetElement.append(resizeWrapper); 'data-cke-widget-upcasted',
} 'data-cke-widget-keep-attr',
widget.wrapper.append(widgetElement, true); 'data-widget',
widget.element = widgetElement; ];
widget.element.setAttribute('data-widget', widget.name);
} else { // Create a new widget element (copying some attributes from the old widget element).
const newWidgetElement = editor.document.createElement('span');
newWidgetElement.addClass('cke_widget_element');
newWidgetElement.setAttributes(widgetElementAttrs.reduce((attrs, name) => {
attrs[name] = oldWidgetElement.getAttribute(name);
return attrs;
}, {}));
if (resizeWrapper) { if (resizeWrapper) {
widget.element.append(resizeWrapper, true); newWidgetElement.append(resizeWrapper);
} }
// Replace the widget element.
widget.wrapper.append(newWidgetElement, true);
widget.element = newWidgetElement;
// Cleanup the old widget element.
oldWidgetElement.removeClass('cke_widget_element');
oldWidgetElement.removeAttributes(widgetElementAttrs);
} else if (resizeWrapper) {
// Simply append the image resize wrapper to the widget element.
widget.element.append(resizeWrapper, true);
} }
} }
...@@ -634,49 +651,25 @@ ...@@ -634,49 +651,25 @@
originalData.call(this); originalData.call(this);
}; };
var originalUpcast = imageWidget.upcast; const originalDowncast = imageWidget.downcast;
// @param {CKEDITOR.htmlParser.element} element imageWidget.downcast = function (...args) {
// @param {Object} data
imageWidget.upcast = function (element, data) {
var el = originalUpcast.apply(this, arguments);
if (el && element.name === 'img') {
// Wrap the image with a span. This span will be used to place the resize span during the init of the image
// widget.
var span = new CKEDITOR.htmlParser.element( 'span' );
el.wrapWith(span);
el = span;
}
return el;
};
var originalDowncast = imageWidget.downcast;
imageWidget.downcast = function (element) {
const alignment = this.data.alignment; const alignment = this.data.alignment;
var el = originalDowncast.apply(this, arguments); const element = originalDowncast.apply(this, args);
downcastLegacyCenter(el, alignment); downcastLegacyCenter(element, alignment);
var isNotCaptioned = this.parts.caption === null; if (!this.parts.caption) {
if (isNotCaptioned) { // Image widget without caption.
let img; // Remove the wrapping span used for the resize handle.
if(el.name === 'img') { const img = element.name === 'img' ? element : element.findOne('img', true);
img = el; let imageResizeWrapper = img;
} else { while (imageResizeWrapper && imageResizeWrapper.name !== 'span' && imageResizeWrapper !== element) {
img = el.findOne('img', true); imageResizeWrapper = imageResizeWrapper.parent;
} }
// Cleanup and remove the wrapping span used for the resize caret. if (imageResizeWrapper?.name === 'span' && imageResizeWrapper !== element) {
delete img.attributes['data-widget']; imageResizeWrapper.replaceWith(imageResizeWrapper.children[0]);
if(el.children[0]) {
var firstChild = el.children[0];
if (firstChild.children[0]) {
firstChild.replaceWith(firstChild.children[0]);
}
} }
} }
// Safety data-widget removal as I noticed an additional data-widget being persisted. I did not identify the return element;
// exact reproduction steps though.
delete el.attributes['data-widget'];
return el;
}; };
} }
}); });
......
...@@ -634,11 +634,10 @@ void quickInsertImageOtherPage(TestUtils setup, ...@@ -634,11 +634,10 @@ void quickInsertImageOtherPage(TestUtils setup,
createAndLoginStandardUser(setup); createAndLoginStandardUser(setup);
// Create a child page. // Create a child page.
DocumentReference otherPage = new DocumentReference("attachmentOtherPage", DocumentReference otherPage = new DocumentReference("attachmentOtherPage",
testReference.getLastSpaceReference()); testReference.getLastSpaceReference());
// Attach an image named "otherImage.gif" to the other page. // Attach an image named "otherImage.gif" to the other page.
String otherAttachmentName = "otherImage.gif"; String otherAttachmentName = "otherImage.gif";
AttachmentReference attachmentReference = new AttachmentReference(otherAttachmentName, otherPage);
uploadAttachment(setup, otherPage, otherAttachmentName); uploadAttachment(setup, otherPage, otherAttachmentName);
String attachmentName = "image.gif"; String attachmentName = "image.gif";
...@@ -817,6 +816,7 @@ void pasteAndEditExternalImage(TestUtils setup, TestReference testReference) thr ...@@ -817,6 +816,7 @@ void pasteAndEditExternalImage(TestUtils setup, TestReference testReference) thr
CKEditor editor = new CKEditor("content").waitToLoad(); CKEditor editor = new CKEditor("content").waitToLoad();
RichTextAreaElement richTextArea = editor.getRichTextArea(); RichTextAreaElement richTextArea = editor.getRichTextArea();
richTextArea.clear();
richTextArea.sendKeys(Keys.chord(Keys.CONTROL, "v")); richTextArea.sendKeys(Keys.chord(Keys.CONTROL, "v"));
richTextArea.verifyContent(content -> { richTextArea.verifyContent(content -> {
content.getImages().get(0).click(); content.getImages().get(0).click();
...@@ -864,7 +864,7 @@ void editListWithImage(TestUtils setup, TestReference testReference) throws Exce ...@@ -864,7 +864,7 @@ void editListWithImage(TestUtils setup, TestReference testReference) throws Exce
@Test @Test
@Order(20) @Order(20)
void editImageWithDataWidgetAttribute(TestUtils setup, TestReference testReference) throws Exception void editImageWithDataWidgetAttribute(TestUtils setup, TestReference testReference)
{ {
setup.loginAsSuperAdmin(); setup.loginAsSuperAdmin();
ViewPage page = setup.createPage(testReference, "[[image:image.gif||data-widget='uploadimage']]"); ViewPage page = setup.createPage(testReference, "[[image:image.gif||data-widget='uploadimage']]");
...@@ -876,6 +876,32 @@ void editImageWithDataWidgetAttribute(TestUtils setup, TestReference testReferen ...@@ -876,6 +876,32 @@ void editImageWithDataWidgetAttribute(TestUtils setup, TestReference testReferen
assertEquals("[[image:image.gif]]", savedPage.editWiki().getContent()); assertEquals("[[image:image.gif]]", savedPage.editWiki().getContent());
} }
@Test
@Order(21)
void editLegacyCenteredImageWithLink(TestUtils setup, TestReference testReference) throws Exception
{
// Run the tests as a normal user. We make the user advanced only to enable the Edit drop down menu.
createAndLoginStandardUser(setup);
// Upload an attachment to test with.
String attachmentName = "image.gif";
ViewPage newPage = uploadAttachment(setup, testReference, attachmentName);
WikiEditPage wikiEditPage = newPage.editWiki();
wikiEditPage.setContent("(% style='text-align: center' %)\n"
+ "[[~[~[image:image.gif~]~]>>Target.Page]]");
ViewPage viewPage = wikiEditPage.clickSaveAndView();
// Move to the WYSIWYG edition page.
WYSIWYGEditPage wysiwygEditPage = viewPage.editWYSIWYG();
new CKEditor("content").waitToLoad();
ViewPage savedPage = wysiwygEditPage.clickSaveAndView();
assertEquals("[[~[~[image:image.gif~|~|data-xwiki-image-style-alignment=\"center\"~]~]>>Target.Page]]",
savedPage.editWiki().getContent());
}
/** /**
* Initialize a page with some content and an image. Then, copy its displayed content in the clipboard. * Initialize a page with some content and an image. Then, copy its displayed content in the clipboard.
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment