Skip to content

Commit

Permalink
Merge 0422241 into 5107fd7
Browse files Browse the repository at this point in the history
  • Loading branch information
tuticapi committed May 27, 2020
2 parents 5107fd7 + 0422241 commit 782ea67
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 27 deletions.
102 changes: 76 additions & 26 deletions mockup/patterns/tinymce/js/links.js
Expand Up @@ -485,6 +485,8 @@ define([
externalImageText: this.options.text.externalImageText,
altText: this.options.text.alt,
imageAlignText: this.options.text.imageAlign,
captionFromDescriptionText: this.options.text.captionFromDescription,
captionText: this.options.text.caption,
scaleText: this.options.text.scale,
imageScales: this.options.imageScales,
cancelBtn: this.options.text.cancelBtn,
Expand All @@ -506,7 +508,9 @@ define([
self.$alt = $('input[name="alt"]', self.modal.$modal);
self.$align = $('select[name="align"]', self.modal.$modal);
self.$scale = $('select[name="scale"]', self.modal.$modal);

self.$captionFromDescription = $('input[name="captionFromDescription"]', self.modal.$modal);
self.$caption = $('textarea[name="caption"]', self.modal.$modal);

/* load up all the link types */
_.each(self.options.linkTypes, function(type) {
var $container = $('.linkType.' + type + ' .main', self.modal.$modal);
Expand All @@ -525,6 +529,15 @@ define([
}
});
});

self.$captionFromDescription.change(function () {
if (this.checked) {
self.$caption.prop('disabled', true);
} else {
self.$caption.prop('disabled', false);
}
});

},

getLinkUrl: function() {
Expand Down Expand Up @@ -584,17 +597,23 @@ define([
updateImage: function(src) {
var self = this;
var title = self.$title.val();
var captionFromDescription = self.$captionFromDescription.prop('checked')

self.tiny.focus();
self.tiny.selection.setRng(self.rng);

var cssclasses = ['image-richtext', self.$align.val()];
if (captionFromDescription) {
cssclasses.push('captioned');
}

var data = $.extend(true, {}, {
src: src,
title: title ? title : null,
alt: self.$alt.val(),
'class': self.$align.val(),
'class': cssclasses.join(' '),
'data-linkType': self.linkType,
'data-scale': self.$scale.val()
'data-scale': self.$scale.val(),
}, self.linkTypes[self.linkType].attributes());
if (self.imgElm && !self.imgElm.getAttribute('data-mce-object')) {
data.width = self.dom.getAttrib(self.imgElm, 'width');
Expand All @@ -610,14 +629,29 @@ define([
};
}

if (!self.imgElm) {
data.id = '__mcenew';
self.tiny.insertContent(self.dom.createHTML('img', data));
self.imgElm = self.dom.get('__mcenew');
self.dom.setAttrib(self.imgElm, 'id', null);
if (self.imgElm) {
self.dom.remove(self.imgElm);
}
if (self.captionElm) {
self.dom.remove(self.captionElm);
}
if (self.figureElm) {
self.dom.remove(self.figureElm);
}

data.id = '__mcenew';
var html_inner = self.dom.createHTML('img', data);
var caption = self.$caption.val();
var html_string;
if (caption && ! captionFromDescription) {
html_inner += '\n' + self.dom.createHTML('figcaption', {}, caption);
html_string = self.dom.createHTML('figure', {}, html_inner);
} else {
self.dom.setAttribs(self.imgElm, data);
html_string = html_inner;
}
self.tiny.insertContent(html_string);
self.imgElm = self.dom.get('__mcenew');
self.dom.setAttrib(self.imgElm, 'id', null);

waitLoad(self.imgElm);
if (self.imgElm.complete) {
Expand Down Expand Up @@ -737,31 +771,47 @@ define([
self.data.title = value;
}

self.selection = self.tiny.selection;
self.tiny.focus();
var selectedElm = self.imgElm = self.selection.getNode();
self.anchorElm = self.dom.getParent(selectedElm, 'a[href]');
self.anchorElm = self.dom.getParent(self.selectedElm, 'a[href]');

var linkType;
var linkType
if (self.isImageMode()) {
if (self.imgElm.nodeName !== 'IMG') {
// try finding elsewhere
if (self.anchorElm) {
var imgs = self.anchorElm.getElementsByTagName('img');
if (imgs.length > 0) {
self.imgElm = imgs[0];
self.focusElement(self.imgElm);
}
}
}
if (self.imgElm.nodeName !== 'IMG') {
// okay, still no image, unset
self.imgElm = null;
var figure;
var img;
var caption;
if (self.selectedElm.nodeName === 'FIGURE') {
figure = self.selectedElm;
img = figure.querySelector('img');
caption = figure.querySelector('figcaption');
} else if (self.selectedElm.nodeName === 'IMG') {
figure = $(self.selectedElm).closest('figure');
figure = figure.length ? figure[0] : undefined;
img = self.selectedElm;
caption = figure ? figure.querySelector('figcaption') : undefined;
} else if (self.selectedElm.nodeName === 'FIGCAPTION') {
figure = $(self.selectedElm).closest('figure');
figure = figure.length ? figure[0] : undefined;
img = figure ? figure.querySelector('img') : undefined;
caption = self.selectedElm;
}

self.imgElm = img;
self.figureElm = figure;
self.captionElm = caption;

if (self.imgElm) {
var src = self.dom.getAttrib(self.imgElm, 'src');
self.$title.val(self.dom.getAttrib(self.imgElm, 'title'));
self.$alt.val(self.dom.getAttrib(self.imgElm, 'alt'));

if ($(self.imgElm).hasClass('captioned')) {
self.$captionFromDescription.prop('checked', true);
self.$caption.prop('disabled', true);
}
if (self.captionElm) {
self.$caption.val(self.captionElm.innerHTML);
}

linkType = self.dom.getAttrib(self.imgElm, 'data-linktype');
if (linkType) {
self.linkType = linkType;
Expand Down
4 changes: 3 additions & 1 deletion mockup/patterns/tinymce/pattern.js
Expand Up @@ -3,7 +3,7 @@
* Options:
* relatedItems(object): Related items pattern options. ({ attributes: ["UID", "Title", "Description", "getURL", "portal_type", "path", "ModificationDate"], batchSize: 20, basePath: "/", vocabularyUrl: null, width: 500, maximumSelectionSize: 1, placeholder: "Search for item on site..." })
* upload(object): Upload pattern options. ({ attributes: look at upload pattern for getting the options list })
* text(object): Translation strings ({ insertBtn: "Insert", cancelBtn: "Cancel", insertHeading: "Insert link", title: "Title", internal: "Internal", external: "External", email: "Email", anchor: "Anchor", subject: "Subject" image: "Image", imageAlign: "Align", scale: "Size", alt: "Alternative Text", externalImage: "External Image URI"})
* text(object): Translation strings ({ insertBtn: "Insert", cancelBtn: "Cancel", insertHeading: "Insert link", title: "Title", internal: "Internal", external: "External", email: "Email", anchor: "Anchor", subject: "Subject" image: "Image", imageAlign: "Align", scale: "Size", alt: "Alternative Text", captionFromDescription: "Show Image Caption from Image Description", caption: "Image Caption", externalImage: "External Image URI"})
* imageScales(string): Image scale name/value object-array or JSON string for use in the image dialog.
* targetList(array): TODO ([ {text: "Open in this window / frame", value: ""}, {text: "Open in new window", value: "_blank"}, {text: "Open in parent window / frame", value: "_parent"}, {text: "Open in top frame (replaces all frames)", value: "_top"}])
* imageTypes(string): TODO ('Image')
Expand Down Expand Up @@ -148,6 +148,8 @@ define([
scale: _t('Size'),
alt: _t('Alternative Text'),
insertImageHelp: _t('Specify an image. It can be on this site already (Internal Image), an image you upload (Upload), or from an external site (External Image).'),
captionFromDescription: _t('Show Image Caption from Image Description'),
caption: _t('Image Caption'),
internalImage: _t('Internal Image'),
externalImage: _t('External Image'),
externalImageText: _t('External Image URL (can be relative within this site or absolute if it starts with http:// or https://)'),
Expand Down
10 changes: 10 additions & 0 deletions mockup/patterns/tinymce/templates/image.xml
Expand Up @@ -60,6 +60,16 @@
<label><%- altText %></label>
<input type="text" name="alt" />
</div>
<div class="form-group captionFromDescription">
<label>
<input type="checkbox" name="captionFromDescription" />
<%- captionFromDescriptionText %>
</label>
</div>
<div class="form-group caption">
<label><%- captionText %></label>
<textarea name="caption" />
</div>
<div class="form-group align">
<label><%- imageAlignText %></label>
<select name="align">
Expand Down
57 changes: 57 additions & 0 deletions mockup/tests/pattern-tinymce-test.js
Expand Up @@ -336,7 +336,64 @@ define([
pattern.imageModal.$scale.find('[value="customscale"]')[0].selected = true;
expect(pattern.imageModal.getLinkUrl()).to.equal('resolveuid/foobar/@@images/image/customscale');
});
it('test add image with and without caption', function() {
var pattern = createTinymce({
prependToUrl: 'resolveuid/',
linkAttribute: 'UID',
prependToScalePart: '/@@images/image/'
});

// Add an image caption.
pattern.addImageClicked();
pattern.imageModal.linkTypes.image.getEl().select2('data', {
UID: 'foobar',
portal_type: 'Document',
Title: 'Foobar',
path: '/foobar'
});
pattern.imageModal.$caption.val('hello.');
pattern.imageModal.$button.click();
var content = pattern.tiny.getContent();

expect(content).to.contain('<figure><img');
expect(content).to.contain('<figcaption>hello.</figcaption>');
expect(content).to.contain('image-richtext');// new image-richtext class.

// Remove the image caption. The <img> isn't wrapped then in a <figure> tag.
pattern.addImageClicked();
pattern.imageModal.linkTypes.image.getEl().select2('data', {
UID: 'foobar',
portal_type: 'Document',
Title: 'Foobar',
path: '/foobar'
});
pattern.imageModal.$caption.val('');
pattern.imageModal.$button.click();
content = pattern.tiny.getContent();

expect(content).to.not.contain('<figure>');
expect(content).to.not.contain('<figcaption>');
expect(content).to.contain('<img');
expect(content).to.contain('image-richtext'); // new image-richtext class.

// Use image captions from the image description.
pattern.addImageClicked();
pattern.imageModal.linkTypes.image.getEl().select2('data', {
UID: 'foobar',
portal_type: 'Document',
Title: 'Foobar',
path: '/foobar'
});
pattern.imageModal.$captionFromDescription.prop('checked', true);
pattern.imageModal.$button.click();
content = pattern.tiny.getContent();

expect(content).to.not.contain('<figure>');
expect(content).to.not.contain('<figcaption>');
expect(content).to.contain('<img');
expect(content).to.contain('image-richtext'); // new image-richtext class.
expect(content).to.contain('captioned'); // new image-richtext class.
});
it('test adds data attributes', function() {
var pattern = createTinymce();
pattern.tiny.setContent('<p>blah</p>');
Expand Down
2 changes: 2 additions & 0 deletions news/977.bugfix
@@ -0,0 +1,2 @@
- TinyMCE: Add support for image captions.
- If an image caption is given, the <img> tag is wrapped within a <figure> tag and a <figcaption> tag is added.

0 comments on commit 782ea67

Please sign in to comment.