Skip to content

Commit

Permalink
Squashed 'libs/editor/' changes from a35d654..0f6fba8
Browse files Browse the repository at this point in the history
0f6fba8 Merge pull request #334 from wordpress-mobile/issue/292-backspace-bug
041f285 Changed ZSSEditor.getYCaretInfo to find parent contenteditable divs correctly
92cb325 Fixed an issue with losing cursor focus on API<19
0c2b5fd Made blockquote parsing handle DIVs tags as paragraphs
c62ce8e Convert divs to paragraph tags when extracting the HTML from the editor
f5e5d26 Changed getFocusedField to use this.focusedField, in order to avoid div targeting issues now that paragraphs are also divs
c925ebd Add line height and margin styling to div tags (duplicated from p tags, and excluding the contenteditable and separator divs
eb1677c Drop defaultParagraphSeparator assignment and use divs instead of ps for paragraphs (WebView default)
5e90578 Merge pull request #333 from wordpress-mobile/issue/258-remove-failed-uploads-when-switching-to-html-mode
9a0ef46 Merge commit '4c9324cf1eee00b66c76e0d5a917c86e1293a845' into develop
ac96e74 fix #258: prompt the user to delete failed uploads before switching to HTML mode
b856f7b update to android-gradle 2.0.0-rc1
e6f4e6b Add missing classes for images inserted from media library - also fix a bug with undefined alt text
31d2970 Add missing attributes for uploaded images
ce6ab9d update to android-gradle-2.0.0-rc1

git-subtree-dir: libs/editor
git-subtree-split: 0f6fba8fc434c4007c7cdd300c4dd9fa2df5a218
  • Loading branch information
maxme committed Apr 6, 2016
1 parent 4c9324c commit c5b98a8
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 59 deletions.
2 changes: 1 addition & 1 deletion WordPressEditor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-beta7'
classpath 'com.android.tools.build:gradle:2.0.0-rc1'
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
Expand Down Expand Up @@ -407,55 +408,82 @@ protected void initJsEditor() {
}
}

@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.format_bar_button_html) {
mEditorFragmentListener.onTrackableEvent(TrackableEvent.HTML_BUTTON_TAPPED);
public void checkForFailedUploadAndSwitchToHtmlMode(final ToggleButton toggleButton) {
// Show an Alert Dialog asking the user if he wants to remove all failed media before upload
if (hasFailedMediaUploads()) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.editor_failed_uploads_switch_html)
.setPositiveButton(R.string.editor_remove_failed_uploads, new OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Clear failed uploads and switch to HTML mode
removeAllFailedMediaUploads();
toggleHtmlMode(toggleButton);
}
}).setNegativeButton(android.R.string.cancel, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toggleButton.setChecked(false);
}
});
builder.create().show();
} else {
toggleHtmlMode(toggleButton);
}
}

// Don't switch to HTML mode if currently uploading media
if (!mUploadingMedia.isEmpty()) {
((ToggleButton) v).setChecked(false);
private void toggleHtmlMode(final ToggleButton toggleButton) {
mEditorFragmentListener.onTrackableEvent(TrackableEvent.HTML_BUTTON_TAPPED);

if (isAdded()) {
ToastUtils.showToast(getActivity(), R.string.alert_html_toggle_uploading, ToastUtils.Duration.LONG);
}
return;
// Don't switch to HTML mode if currently uploading media
if (!mUploadingMedia.isEmpty()) {
toggleButton.setChecked(false);

if (isAdded()) {
ToastUtils.showToast(getActivity(), R.string.alert_html_toggle_uploading, ToastUtils.Duration.LONG);
}
return;
}

clearFormatBarButtons();
updateFormatBarEnabledState(true);
clearFormatBarButtons();
updateFormatBarEnabledState(true);

if (((ToggleButton) v).isChecked()) {
mSourceViewTitle.setText(getTitle());
if (toggleButton.isChecked()) {
mSourceViewTitle.setText(getTitle());

SpannableString spannableContent = new SpannableString(getContent());
HtmlStyleUtils.styleHtmlForDisplay(spannableContent);
mSourceViewContent.setText(spannableContent);
SpannableString spannableContent = new SpannableString(getContent());
HtmlStyleUtils.styleHtmlForDisplay(spannableContent);
mSourceViewContent.setText(spannableContent);

mWebView.setVisibility(View.GONE);
mSourceView.setVisibility(View.VISIBLE);
mWebView.setVisibility(View.GONE);
mSourceView.setVisibility(View.VISIBLE);

mSourceViewContent.requestFocus();
mSourceViewContent.setSelection(0);
mSourceViewContent.requestFocus();
mSourceViewContent.setSelection(0);

InputMethodManager imm = ((InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE));
imm.showSoftInput(mSourceViewContent, InputMethodManager.SHOW_IMPLICIT);
} else {
mWebView.setVisibility(View.VISIBLE);
mSourceView.setVisibility(View.GONE);
InputMethodManager imm = ((InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE));
imm.showSoftInput(mSourceViewContent, InputMethodManager.SHOW_IMPLICIT);
} else {
mWebView.setVisibility(View.VISIBLE);
mSourceView.setVisibility(View.GONE);

mTitle = mSourceViewTitle.getText().toString();
mContentHtml = mSourceViewContent.getText().toString();
updateVisualEditorFields();
mTitle = mSourceViewTitle.getText().toString();
mContentHtml = mSourceViewContent.getText().toString();
updateVisualEditorFields();

// Update the list of failed media uploads
mWebView.execJavaScriptFromString("ZSSEditor.getFailedMedia();");
// Update the list of failed media uploads
mWebView.execJavaScriptFromString("ZSSEditor.getFailedMedia();");

// Reset selection to avoid buggy cursor behavior
mWebView.execJavaScriptFromString("ZSSEditor.resetSelectionOnField('zss_field_content');");
}
// Reset selection to avoid buggy cursor behavior
mWebView.execJavaScriptFromString("ZSSEditor.resetSelectionOnField('zss_field_content');");
}
}

@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.format_bar_button_html) {
checkForFailedUploadAndSwitchToHtmlMode((ToggleButton) v);
} else if (id == R.id.format_bar_button_media) {
mEditorFragmentListener.onTrackableEvent(TrackableEvent.MEDIA_BUTTON_TAPPED);
((ToggleButton) v).setChecked(false);
Expand Down
3 changes: 3 additions & 0 deletions WordPressEditor/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,7 @@
<string name="image_thumbnail">Image thumbnail</string>


<string name="editor_failed_uploads_switch_html">Some media uploads have failed. You can\'t switch to HTML mode
in this state. Remove all failed uploads and continue?</string>
<string name="editor_remove_failed_uploads">Remove failed uploads</string>
</resources>
2 changes: 1 addition & 1 deletion example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-beta7'
classpath 'com.android.tools.build:gradle:2.0.0-rc1'
}
}

Expand Down
69 changes: 49 additions & 20 deletions libs/editor-common/assets/ZSSRichTextEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const NodeName = {
LI: "LI",
CODE: "CODE",
SPAN: "SPAN",
BR: "BR"
BR: "BR",
DIV: "DIV",
BODY: "BODY"
};

// The editor object
Expand Down Expand Up @@ -63,7 +65,7 @@ ZSSEditor.editableFields = {};
ZSSEditor.lastTappedNode = null;

// The default paragraph separator
ZSSEditor.defaultParagraphSeparator = 'p';
ZSSEditor.defaultParagraphSeparator = 'div';

// Video format tags supported by the [video] shortcode: https://codex.wordpress.org/Video_Shortcode
// mp4, m4v and webm prioritized since they're supported by the stock player as of Android API 23
Expand Down Expand Up @@ -92,7 +94,6 @@ ZSSEditor.init = function() {
}

document.execCommand('insertBrOnReturn', false, false);
document.execCommand('defaultParagraphSeparator', false, this.defaultParagraphSeparator);

var editor = $('div.field').each(function() {
var editableField = new ZSSField($(this));
Expand Down Expand Up @@ -172,7 +173,7 @@ ZSSEditor.formatNewLine = function(e) {
this.formatNewLineInsideBlockquote(e);
} else if (!ZSSEditor.isCommandEnabled('insertOrderedList')
&& !ZSSEditor.isCommandEnabled('insertUnorderedList')) {
document.execCommand('formatBlock', false, 'p');
document.execCommand('formatBlock', false, 'div');
}
} else {
e.preventDefault();
Expand All @@ -192,20 +193,13 @@ ZSSEditor.getField = function(fieldId) {
};

ZSSEditor.getFocusedField = function() {
var currentField = $(this.closerParentNodeWithName('div'));
var currentField = $(this.findParentContenteditableDiv());
var currentFieldId;

if (currentField) {
currentFieldId = currentField.attr('id');
}

while (currentField && (!currentFieldId || this.editableFields[currentFieldId] == null)) {
currentField = this.closerParentNodeStartingAtNode('div', currentField);
if (currentField) {
currentFieldId = currentField.attr('id');
}
}

if (!currentFieldId) {
ZSSEditor.resetSelectionOnField('zss_field_content');
currentFieldId = 'zss_field_content';
Expand Down Expand Up @@ -480,7 +474,7 @@ ZSSEditor.getYCaretInfo = function() {
//
if (needsToWorkAroundNewlineBug) {
var closerParentNode = ZSSEditor.closerParentNode();
var closerDiv = ZSSEditor.closerParentNodeWithName('div');
var closerDiv = ZSSEditor.findParentContenteditableDiv();

var fontSize = $(closerParentNode).css('font-size');
var lineHeight = Math.floor(parseInt(fontSize.replace('px','')) * 1.5);
Expand Down Expand Up @@ -654,7 +648,7 @@ ZSSEditor.setHeading = function(heading) {
};

ZSSEditor.setParagraph = function() {
var formatTag = "p";
var formatTag = "div";
var formatBlock = document.queryCommandValue('formatBlock');

if (formatBlock.length > 0 && formatBlock.toLowerCase() == formatTag) {
Expand Down Expand Up @@ -1028,8 +1022,11 @@ ZSSEditor.updateImage = function(url, alt) {
};

ZSSEditor.insertImage = function(url, remoteId, alt) {
var html = '<img src="' + url + '" alt="' + alt + '" class="wp-image-' + remoteId + '" />';

var html = '<img src="' + url + '" class="wp-image-' + remoteId + ' alignnone size-full';
if (alt) {
html += '" alt="' + alt
}
html += '"/>'
this.insertHTML(this.wrapInParagraphTags(html));
this.sendEnabledStyles();
};
Expand Down Expand Up @@ -1138,6 +1135,9 @@ ZSSEditor.finishLocalImageSwap = function(image, imageNode, imageNodeIdentifier,
imageNode.attr('remoteurl', image.getAttribute("remoteurl"));
}
imageNode.attr('src', image.src);
// Set extra attributes and classes used by WordPress
imageNode.attr({'width': image.width, 'height': image.height});
imageNode.addClass("alignnone size-full");
ZSSEditor.markImageUploadDone(imageNodeIdentifier);
var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments();
ZSSEditor.callback("callback-input", joinedArguments);
Expand Down Expand Up @@ -2289,7 +2289,7 @@ ZSSEditor.removeVisualFormatting = function( html ) {
str = ZSSEditor.replaceVideoPressVideosForShortcode( str );
str = ZSSEditor.replaceVideosForShortcode( str );
return str;
}
};

ZSSEditor.insertHTML = function(html) {
document.execCommand('insertHTML', false, html);
Expand Down Expand Up @@ -2618,7 +2618,9 @@ ZSSEditor.getAncestorElementForSettingBlockquote = function(range) {
|| parentElement.nodeName == NodeName.OL
|| parentElement.nodeName == NodeName.LI
|| parentElement.nodeName == NodeName.CODE
|| parentElement.nodeName == NodeName.SPAN)) {
|| parentElement.nodeName == NodeName.SPAN
// Include nested divs, but ignore the parent contenteditable field div
|| (parentElement.nodeName == NodeName.DIV && parentElement.parentElement.nodeName != NodeName.BODY))) {
parentElement = parentElement.parentNode;
}

Expand Down Expand Up @@ -2740,6 +2742,23 @@ ZSSEditor.hasPreviousSiblingWithName = function(node, siblingNodeName) {

// MARK: - Parent nodes & tags

ZSSEditor.findParentContenteditableDiv = function() {
var parentNode = null;
var selection = window.getSelection();
if (selection.rangeCount < 1) {
return null;
}
var range = selection.getRangeAt(0).cloneRange();

var referenceNode = this.closerParentNodeWithNameRelativeToNode('div', range.commonAncestorContainer);

while (referenceNode.parentNode.nodeName != NodeName.BODY) {
referenceNode = this.closerParentNodeWithNameRelativeToNode('div', referenceNode.parentNode);
}

return referenceNode;
};

ZSSEditor.closerParentNode = function() {

var parentNode = null;
Expand Down Expand Up @@ -3246,7 +3265,7 @@ ZSSField.prototype.wrapCaretInParagraphIfNecessary = function()
var range = selection.getRangeAt(0);

if (range.startContainer == range.endContainer) {
var paragraph = document.createElement("p");
var paragraph = document.createElement("div");
var textNode = document.createTextNode("&#x200b;");

paragraph.appendChild(textNode);
Expand Down Expand Up @@ -3285,7 +3304,11 @@ ZSSField.prototype.isEmpty = function() {
};

ZSSField.prototype.getHTML = function() {
var html = wp.saveText(this.wrappedObject.html());
var html = this.wrappedObject.html();
if (ZSSEditor.defaultParagraphSeparator == 'div') {
html = html.replace(/(<div)/igm, '<p').replace(/<\/div>/igm, '</p>');
}
html = wp.saveText(html);
html = ZSSEditor.removeVisualFormatting( html );
return html;
};
Expand All @@ -3312,6 +3335,12 @@ ZSSField.prototype.setHTML = function(html) {
ZSSEditor.currentEditingImage = null;
var mutatedHTML = wp.loadText(html);
mutatedHTML = ZSSEditor.applyVisualFormatting(mutatedHTML);

if (ZSSEditor.defaultParagraphSeparator == 'div') {
// Replace the paragraph tags we get from wpload with divs
mutatedHTML = mutatedHTML.replace(/(<p)/igm, '<div').replace(/<\/p>/igm, '</div>');
}

this.wrappedObject.html(mutatedHTML);
};

Expand Down
9 changes: 9 additions & 0 deletions libs/editor-common/assets/editor-android.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ video::-webkit-media-controls-fullscreen-button {
display: none;
}

/* Duplicates paragraph tag formatting for div tags, which are needed on Android API 19+ due to autocorrect issues:
https://bugs.chromium.org/p/chromium/issues/detail?id=599890
*/
div:not(.field):not(#separatorDiv) {
line-height: 24px;
margin-top: 0px;
margin-bottom: 24px;
}

/* --- API<19 workarounds --- */

/* Used only on older APIs (API<19), which don't support CSS filter effects (specifically, blur). */
Expand Down

0 comments on commit c5b98a8

Please sign in to comment.