Skip to content

Commit

Permalink
Squashed 'libs/editor/' changes from a2a6a7c..a92ad9d
Browse files Browse the repository at this point in the history
a92ad9d Merge pull request #424 from wordpress-mobile/issue/423-image-caption-backspace
c04f955 add mocha call to the README
cb1cb3c Don't add space in front of image captions
3f15fa3 Fixed paragraph formatting for captions when converting from HTML to visual
fc0661e Added JS tests for images with captions
daf9b96 Fixed mislabeled JS tests
5022799 Extended Formatter.convertPToDiv to apply paragraph formatting to images with captions
0594930 Removed jQuery dependency from Formatter.applyCaptionFormatting()
cf03097 When adding caption formatting to an image, set the caret below the image
2b30987 Adjust handleCaptionNewLine() to handle pressing enter in the middle of the caption text
44fbd87 When pressing enter inside an image caption, strip caption styling from the new line
24f2423 Make image caption nodes editable

git-subtree-dir: libs/editor
git-subtree-split: a92ad9df3062c875b921f5bbb4a11b6dda11136f
  • Loading branch information
maxme committed Jun 23, 2016
1 parent 49ac398 commit d0d8dd4
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 11 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ With npm and Mocha installed, from within `libs/editor-common/assets/test`, run:

npm install chai

It should now be possible to run the tests using `mocha` inside `libs/editor-common/assets`.
And then run `mocha` inside `libs/editor-common/assets`:

cd libs/editor-common/assets; mocha; cd -

## LICENSE ##

Expand Down
35 changes: 34 additions & 1 deletion libs/editor-common/assets/ZSSRichTextEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1942,11 +1942,15 @@ ZSSEditor.updateCurrentImageMeta = function( imageMetaString ) {
// in certain cases, modify the current and inserted markup depending on what
// elements surround the targeted node. This approach is safer.
var node = ZSSEditor.findImageCaptionNode( ZSSEditor.currentEditingImage );
var parent = node.parentNode;

node.insertAdjacentHTML( 'afterend', html );
// Use {node}.{parent}.removeChild() instead of {node}.remove(), since Android API<19 doesn't support Node.remove()
node.parentNode.removeChild(node);

ZSSEditor.currentEditingImage = null;

ZSSEditor.setFocusAfterElement(parent);
}

ZSSEditor.applyImageSelectionFormatting = function( imageNode ) {
Expand Down Expand Up @@ -2148,7 +2152,7 @@ ZSSEditor.createImageFromMeta = function( props ) {
html = wp.shortcode.string({
tag: 'caption',
attrs: shortcode,
content: html + ' ' + props.caption
content: html + props.caption
});

html = Formatter.applyVisualFormatting( html );
Expand Down Expand Up @@ -3227,6 +3231,9 @@ ZSSField.prototype.handleKeyDownEvent = function(e) {
} else if (sel.isCollapsed && sel.baseOffset == 0 && parentNode && parentNode.nodeName == 'BLOCKQUOTE') {
e.preventDefault();
ZSSEditor.setBlockquote();
// When pressing enter inside an image caption, clear the caption styling from the new line
} else if (parentNode.nodeName == NodeName.SPAN && $(parentNode).hasClass('wp-caption')) {
setTimeout(this.handleCaptionNewLine, 100);
}
}
}
Expand Down Expand Up @@ -3636,6 +3643,32 @@ ZSSField.prototype.wrapCaretInParagraphIfNecessary = function() {
}
};

/**
* @brief Called when enter is pressed inside an image caption. Clears away the span and label tags the new line
* inherits from the caption styling.
*/
ZSSField.prototype.handleCaptionNewLine = function() {
var selectedNode = document.getSelection().baseNode;

var contentsNode;
if (selectedNode.firstChild != null) {
contentsNode = selectedNode.firstChild.cloneNode();
} else {
contentsNode = selectedNode.cloneNode();
}

var parentSpan = selectedNode.parentNode.parentNode;
var parentDiv = parentSpan.parentNode;

var paragraph = document.createElement("div");
paragraph.appendChild(contentsNode);

parentDiv.insertBefore(paragraph, parentSpan);
parentDiv.removeChild(parentSpan);

ZSSEditor.giveFocusToElement(contentsNode);
};

// MARK: - i18n

ZSSField.prototype.isRightToLeftTextEnabled = function() {
Expand Down
21 changes: 14 additions & 7 deletions libs/editor-common/assets/editor-utils-formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ Formatter.videoShortcodeFormats = ["mp4", "m4v", "webm", "ogv", "wmv", "flv"];

Formatter.htmlToVisual = function(html) {
var mutatedHTML = wp.loadText(html);

// Perform extra transformations to properly wrap captioned images in paragraphs
mutatedHTML = mutatedHTML.replace(/^\[caption([^\]]*\])/igm, '<p>[caption$1');
mutatedHTML = mutatedHTML.replace(/([^\n>])\[caption/igm, '$1<br />\n[caption');
mutatedHTML = mutatedHTML.replace(/\[\/caption\]\n(?=<|$)/igm, '[/caption]</p>\n');
mutatedHTML = mutatedHTML.replace(/\[\/caption\]\n(?=[^<])/igm, '[/caption]<br />\n');

return Formatter.applyVisualFormatting(mutatedHTML);
}

Expand All @@ -17,13 +24,13 @@ Formatter.convertPToDiv = function(html) {
// The break tags appear when text and media are separated by only a line break rather than a paragraph break,
// which can happen when inserting media inline and switching to HTML mode and back, or by deleting line breaks
// in HTML mode
mutatedHTML = mutatedHTML.replace(/<br \/>(?=\s*(<a href|<img|<video|<span class="edit-container"))/igm,
mutatedHTML = mutatedHTML.replace(/<br \/>(?=\s*(<img|<a href|<label|<video|<span class="edit-container"))/igm,
'</div><div>');
mutatedHTML = mutatedHTML.replace(/(<img [^<>]*>|<\/a>|<\/video>|<\/span>)<br \/>/igm,
mutatedHTML = mutatedHTML.replace(/(<img [^<>]*>|<\/a>|<\/label>|<\/video>|<\/span>)<br \/>/igm,
function replaceBrWithDivs(match) { return match.substr(0, match.length - 6) + '</div><div>'; });

// Append paragraph-wrapped break tag under media at the end of a post
mutatedHTML = mutatedHTML.replace(/(<img [^<>]*>|<\/a>|<\/video>|<\/span>)[^<>]*<\/div>\s$/igm,
mutatedHTML = mutatedHTML.replace(/(<img [^<>]*>|<\/a>|<\/label>|<\/video>|<\/span>)[^<>]*<\/div>\s$/igm,
function replaceBrWithDivs(match) { return match + '<div><br></div>'; });

return mutatedHTML;
Expand Down Expand Up @@ -68,15 +75,15 @@ Formatter.applyCaptionFormatting = function(match) {
var attrs = match.attrs.named;
// The empty 'onclick' is important. It prevents the cursor jumping to the end
// of the content body when `-webkit-user-select: none` is set and the caption is tapped.
var out = '<label class="wp-temp" data-wp-temp="caption" contenteditable="false" onclick="">';
var out = '<label class="wp-temp" data-wp-temp="caption" onclick="">';
out += '<span class="wp-caption"';

if (attrs.width) {
out += ' style="width:' + attrs.width + 'px; max-width:100% !important;"';
}
$.each(attrs, function(key, value) {
out += " data-caption-" + key + '="' + value + '"';
});
for (var key in attrs) {
out += " data-caption-" + key + '="' + attrs[key] + '"';
}

out += '>';
out += match.content;
Expand Down
16 changes: 14 additions & 2 deletions libs/editor-common/assets/test/test-formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ var imageSrc = 'content://com.android.providers.media.documents/document/image%3
var plainImageHtml = '<img src="' + imageSrc + '" alt="" class="wp-image-123 size-full" width="172" height="244">';
var imageWrappedInLinkHtml = '<a href="' + imageSrc + '">' + plainImageHtml + '</a>';

// Captioned image strings
var imageCaptionShortcode = '[caption width="600" align="alignnone"]' + imageSrc + 'Text[/caption]';
var imageWithCaptionHtml = '<label class="wp-temp" data-wp-temp="caption" onclick="">' +
'<span class="wp-caption" style="width:600px; max-width:100% !important;" data-caption-width="600" ' +
'data-caption-align="alignnone">' + imageSrc + 'Text</span></label>';
var linkedImageCaptionShortcode = '[caption width="600" align="alignnone"]' + imageWrappedInLinkHtml + 'Text[/caption]';
var linkedImageCaptionHtml = '<label class="wp-temp" data-wp-temp="caption" onclick="">' +
'<span class="wp-caption" style="width:600px; max-width:100% !important;" data-caption-width="600" ' +
'data-caption-align="alignnone">' + imageWrappedInLinkHtml + 'Text</span></label>';

// Video strings
var videoSrc = 'content://com.android.providers.media.documents/document/video%3A12966';
var videoShortcode = '[video src="' + videoSrc + '" poster=""][/video]';
Expand All @@ -43,8 +53,10 @@ describe('HTML to Visual formatter should correctly convert', function () {
assert.equal('<p>Some text</p>\n<p>More text</p>\n', formatter.htmlToVisual('Some text\n\nMore text'));
});

testMediaParagraphWrapping('image wrapped in link', plainImageHtml, plainImageHtml);
testMediaParagraphWrapping('image not wrapped in link', imageWrappedInLinkHtml, imageWrappedInLinkHtml);
testMediaParagraphWrapping('non-linked image', plainImageHtml, plainImageHtml);
testMediaParagraphWrapping('linked image', imageWrappedInLinkHtml, imageWrappedInLinkHtml);
testMediaParagraphWrapping('non-linked image, with caption', imageCaptionShortcode, imageWithCaptionHtml);
testMediaParagraphWrapping('linked image, with caption', linkedImageCaptionShortcode, linkedImageCaptionHtml);
testMediaParagraphWrapping('non-VideoPress video', videoShortcode, videoHtml);
testMediaParagraphWrapping('VideoPress video', vpVideoShortcode, vpVideoHtml);
});
Expand Down

0 comments on commit d0d8dd4

Please sign in to comment.