diff --git a/.gitignore b/.gitignore
index 1cbbb457376f..c73b540485b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,3 +50,7 @@ WordPress/src/main/res/values/com_crashlytics_export_strings.xml
# libs
libs/utils
+
+# Node-based JS Tests
+node_modules
+npm-debug.log*
\ No newline at end of file
diff --git a/README.md b/README.md
index 35c05f08a273..eccadbbfbfbe 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,18 @@ Integration testing is done with the [Android testing framework](http://develope
Add new unit tests to `src/test/java/` and integration tests to `stc/androidTest/java/`.
+### JavaScript Tests ###
+
+This project also has unit tests for the JS part of the editor using [Mocha](https://mochajs.org/).
+
+To be able to run the tests, [npm](https://www.npmjs.com/) and Mocha (`npm install -g mocha`) are required.
+
+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`.
+
## LICENSE ##
WordPress-Editor-Android is an Open Source project covered by the [GNU General Public License version 2](LICENSE.md).
diff --git a/WordPressEditor/src/main/res/drawable/format_bar_button_html.xml b/WordPressEditor/src/main/res/drawable/format_bar_button_html.xml
index a17d37c9eb1b..96b241307005 100755
--- a/WordPressEditor/src/main/res/drawable/format_bar_button_html.xml
+++ b/WordPressEditor/src/main/res/drawable/format_bar_button_html.xml
@@ -1,21 +1,18 @@
-
-
+ android:width="44dp"
+ android:height="44dp"
+ android:viewportWidth="44.0"
+ android:viewportHeight="44.0">
+ android:pathData="M13.93,26H12.79v-4.16H9.17V26H8.04v-9h1.13v3.87h3.62V17h1.14V26z"
+ android:fillColor="#A6BCCC"/>
+ android:pathData="M20.97,17.97H18.6V26h-1.13v-8.03h-2.36V17h5.86V17.97z"
+ android:fillColor="#A6BCCC"/>
+ android:pathData="M23.75,17l2.35,7.34L28.45,17h1.46v9h-1.13v-3.51l0.1,-3.51L26.53,26h-0.87l-2.34,-6.99l0.1,3.49V26h-1.13v-9H23.75z"
+ android:fillColor="#A6BCCC"/>
-
\ No newline at end of file
+ android:pathData="M33,25.03h3.53V26h-4.67v-9h1.14V25.03z"
+ android:fillColor="#A6BCCC"/>
+
diff --git a/WordPressEditor/src/main/res/drawable/format_bar_button_html_disabled.xml b/WordPressEditor/src/main/res/drawable/format_bar_button_html_disabled.xml
index b82938df0878..6e5b8074e234 100755
--- a/WordPressEditor/src/main/res/drawable/format_bar_button_html_disabled.xml
+++ b/WordPressEditor/src/main/res/drawable/format_bar_button_html_disabled.xml
@@ -1,15 +1,18 @@
-
-
-
-
\ No newline at end of file
+ android:width="44dp"
+ android:height="44dp"
+ android:viewportWidth="44.0"
+ android:viewportHeight="44.0">
+
+
+
+
+
diff --git a/WordPressEditor/src/main/res/drawable/format_bar_button_html_highlighted.xml b/WordPressEditor/src/main/res/drawable/format_bar_button_html_highlighted.xml
index 1497cf2b596f..331d9a8f98ab 100755
--- a/WordPressEditor/src/main/res/drawable/format_bar_button_html_highlighted.xml
+++ b/WordPressEditor/src/main/res/drawable/format_bar_button_html_highlighted.xml
@@ -1,15 +1,19 @@
-
-
-
-
\ No newline at end of file
+ android:width="44dp"
+ android:height="44dp"
+ android:viewportWidth="44.0"
+ android:viewportHeight="44.0">
+
+
+
+
+
+
diff --git a/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor-common/assets/ZSSRichTextEditor.js
index de5370727d44..d6a412fd6a72 100755
--- a/libs/editor-common/assets/ZSSRichTextEditor.js
+++ b/libs/editor-common/assets/ZSSRichTextEditor.js
@@ -67,10 +67,6 @@ ZSSEditor.lastTappedNode = null;
// The default paragraph separator
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
-ZSSEditor.videoShortcodeFormats = ["mp4", "m4v", "webm", "ogv", "wmv", "flv"];
-
// We use a MutationObserver to catch user deletions of uploading or failed media
// This is only officially supported on API>18; when the WebView doesn't recognize the MutationObserver,
// we fall back to the deprecated DOMNodeRemoved event
@@ -1536,7 +1532,8 @@ ZSSEditor.removeAllFailedMediaUploads = function() {
*
*/
ZSSEditor.insertVideo = function(videoURL, posterURL, videopressID) {
- var html = '';
- this.insertHTMLWrappedInParagraphTags(html);
+ this.insertHTMLWrappedInParagraphTags('' + html);
+
+ // Wrap video in edit-container node for a permanent delete button overlay
+ var videoNode = $('video[id=' + videoId + ']')[0];
+ var selectionNode = this.applyEditContainer(videoNode);
+ videoNode.removeAttribute('id');
+
+ // Remove the zero-width space node (it's not needed now that the paragraph-wrapped video is in place)
+ var zeroWidthNode = selectionNode.previousSibling;
+ if (zeroWidthNode != null && zeroWidthNode.nodeType == 3) {
+ zeroWidthNode.parentNode.removeChild(zeroWidthNode);
+ }
+
+ ZSSEditor.trackNodeForMutation($(selectionNode));
this.sendEnabledStyles();
this.callback("callback-action-finished");
@@ -1658,6 +1668,10 @@ ZSSEditor.replaceLocalVideoWithRemoteVideo = function(videoNodeIdentifier, remot
containerNode.replaceWith(videoNode);
}
+ var selectionNode = this.applyEditContainer(videoNode);
+
+ ZSSEditor.trackNodeForMutation($(selectionNode));
+
var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments();
ZSSEditor.callback("callback-input", joinedArguments);
// We invoke the sendVideoReplacedCallback with a delay to avoid for
@@ -1784,6 +1798,19 @@ ZSSEditor.removeVideo = function(videoNodeIdentifier) {
}
};
+/**
+ * @brief Wrap the video in an edit-container with a delete button overlay.
+ */
+ZSSEditor.applyEditContainer = function(videoNode) {
+ var containerHtml = '';
+ videoNode.insertAdjacentHTML('beforebegin', containerHtml);
+
+ var selectionNode = videoNode.previousSibling;
+ selectionNode.appendChild(videoNode);
+
+ return selectionNode;
+}
+
ZSSEditor.replaceVideoPressVideosForShortcode = function ( html) {
// call methods to restore any transformed content from its visual presentation to its source code.
var regex = /