From 4387667dccc6f668e61a14f964c6e3cd16033fab Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Mon, 29 Feb 2016 14:34:38 +0100 Subject: [PATCH 1/8] add missing comment --- libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index 1c63f1ce7881..2abdc80d3c0e 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -994,7 +994,8 @@ ZSSEditor.markImageUploadDone = function(imageNodeIdentifier) { // Wrap link around image var linkTag = ''; imageNode.wrap(linkTag); - + // We invoke the sendImageReplacedCallback with a delay to avoid for + // it to be ignored by the webview because of the previous callback being done. var thisObj = this; setTimeout(function() { thisObj.sendImageReplacedCallback(imageNodeIdentifier);}, 500); }; From 6b4d174f08ea19957b3d2d00c6cc641508cfebb3 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Mon, 29 Feb 2016 14:37:21 +0100 Subject: [PATCH 2/8] fix wordpress-mobile/WordPress-Editor-Android#300: Retry download onError after an upload --- .../editor-common/assets/ZSSRichTextEditor.js | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index 2abdc80d3c0e..bede6cdfe83a 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -924,24 +924,42 @@ ZSSEditor.replaceLocalImageWithRemoteImage = function(imageNodeIdentifier, remot ZSSEditor.markImageUploadDone(imageNodeIdentifier); var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); ZSSEditor.callback("callback-input", joinedArguments); - + image.onerror = null; + image.classList.add("image-loaded"); } image.onerror = function () { - // Even on an error, we swap the image for the time being. This is because private - // blogs are currently failing to download images due to access privilege issues. - // - imageNode.attr('src', image.src); imageNode.addClass("wp-image-" + remoteImageId); ZSSEditor.markImageUploadDone(imageNodeIdentifier); var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); ZSSEditor.callback("callback-input", joinedArguments); - + // Try to reload the image on error. + ZSSEditor.tryToReload(image, 1); } image.src = remoteImageUrl; }; +ZSSEditor.reloadImage = function(node, nCall) { + if (node.classList.contains("image-loaded")) { + return; + } + console.log("Reloading image:", node, nCall); + node.onerror = tryToReload(node, nCall + 1); + // Force reloading by updating image src + node.src = node.src; +} + +ZSSEditor.tryToReload = function (node, nCall) { + if (nCall > 8) { // 7 tries: 22500 ms total + return; + } + console.log("Image not loaded:", node, "- image reloading will happen soon."); + node.onerror = null; + // reload the image with a variable delay: 500ms, 1000ms, 1500ms, 2000ms, etc. + setTimeout(reloadImage, nCall * 500, node, nCall); +} + /** * @brief Update the progress indicator for the image identified with the value in progress. * From d7dd4f6c477828319fdeb47741ff5e5fea6aa8db Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Wed, 2 Mar 2016 13:41:52 +0100 Subject: [PATCH 3/8] Add back image swapping onError --- libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index bede6cdfe83a..adc20a2943fb 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -926,9 +926,13 @@ ZSSEditor.replaceLocalImageWithRemoteImage = function(imageNodeIdentifier, remot ZSSEditor.callback("callback-input", joinedArguments); image.onerror = null; image.classList.add("image-loaded"); + console.log("Image Loaded!"); } image.onerror = function () { + // Even on an error, we swap the image for the time being - so if the user publishes the post, + // it won't reference a local image. + imageNode.attr('src', image.src); imageNode.addClass("wp-image-" + remoteImageId); ZSSEditor.markImageUploadDone(imageNodeIdentifier); var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); From ef2bcb152ad38b70dd76f0a691a4d24c28878ee1 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Wed, 2 Mar 2016 13:42:19 +0100 Subject: [PATCH 4/8] fix function call errors --- libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index adc20a2943fb..2445ea32d2f5 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -949,7 +949,7 @@ ZSSEditor.reloadImage = function(node, nCall) { return; } console.log("Reloading image:", node, nCall); - node.onerror = tryToReload(node, nCall + 1); + node.onerror = ZSSEditor.tryToReload(node, nCall + 1); // Force reloading by updating image src node.src = node.src; } @@ -961,7 +961,7 @@ ZSSEditor.tryToReload = function (node, nCall) { console.log("Image not loaded:", node, "- image reloading will happen soon."); node.onerror = null; // reload the image with a variable delay: 500ms, 1000ms, 1500ms, 2000ms, etc. - setTimeout(reloadImage, nCall * 500, node, nCall); + setTimeout(ZSSEditor.reloadImage, nCall * 500, node, nCall); } /** From 7fba5d6be908ddb038e8a5c5ee3062b05d44aad6 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 3 Mar 2016 15:12:35 +0100 Subject: [PATCH 5/8] use a remoteUrl attribute to avoid seeing broken image if download failed --- .../editor-common/assets/ZSSRichTextEditor.js | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index 2445ea32d2f5..5ce546c849f7 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -919,49 +919,53 @@ ZSSEditor.replaceLocalImageWithRemoteImage = function(imageNodeIdentifier, remot var image = new Image; image.onload = function () { - imageNode.attr('src', image.src); - imageNode.addClass("wp-image-" + remoteImageId); - ZSSEditor.markImageUploadDone(imageNodeIdentifier); - var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); - ZSSEditor.callback("callback-input", joinedArguments); - image.onerror = null; + ZSSEditor.finishLocalImageSwap(image, imageNode, imageNodeIdentifier, remoteImageId) image.classList.add("image-loaded"); console.log("Image Loaded!"); } image.onerror = function () { - // Even on an error, we swap the image for the time being - so if the user publishes the post, - // it won't reference a local image. - imageNode.attr('src', image.src); - imageNode.addClass("wp-image-" + remoteImageId); - ZSSEditor.markImageUploadDone(imageNodeIdentifier); - var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); - ZSSEditor.callback("callback-input", joinedArguments); + // Add a remoteUrl attribute, remoteUrl and src must be swapped before publishing. + image.setAttribute('remoteurl', image.src); // Try to reload the image on error. - ZSSEditor.tryToReload(image, 1); + ZSSEditor.tryToReload(image, imageNode, imageNodeIdentifier, remoteImageId, 1); } image.src = remoteImageUrl; }; -ZSSEditor.reloadImage = function(node, nCall) { - if (node.classList.contains("image-loaded")) { +ZSSEditor.finishLocalImageSwap = function(image, imageNode, imageNodeIdentifier, remoteImageId) { + imageNode.addClass("wp-image-" + remoteImageId); + if (image.getAttribute("remoteurl")) { + imageNode.attr('src', image.getAttribute("remoteurl")); + } else { + imageNode.attr('src', image.src); + } + ZSSEditor.markImageUploadDone(imageNodeIdentifier); + var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); + ZSSEditor.callback("callback-input", joinedArguments); + image.onerror = null; +} + +ZSSEditor.reloadImage = function(image, imageNode, imageNodeIdentifier, remoteImageId, nCall) { + if (image.classList.contains("image-loaded")) { return; } - console.log("Reloading image:", node, nCall); - node.onerror = ZSSEditor.tryToReload(node, nCall + 1); + console.log("Reloading image:" + nCall + " - " + image.src); + image.onerror = ZSSEditor.tryToReload(image, imageNode, imageNodeIdentifier, remoteImageId, nCall + 1); // Force reloading by updating image src - node.src = node.src; + image.src = image.getAttribute("remoteurl"); } -ZSSEditor.tryToReload = function (node, nCall) { +ZSSEditor.tryToReload = function (image, imageNode, imageNodeIdentifier, remoteImageId, nCall) { if (nCall > 8) { // 7 tries: 22500 ms total + ZSSEditor.finishLocalImageSwap(image, imageNode, imageNodeIdentifier, remoteImageId); return; } - console.log("Image not loaded:", node, "- image reloading will happen soon."); - node.onerror = null; + image.onerror = null; + console.log("Image not loaded"); // reload the image with a variable delay: 500ms, 1000ms, 1500ms, 2000ms, etc. - setTimeout(ZSSEditor.reloadImage, nCall * 500, node, nCall); + setTimeout(ZSSEditor.reloadImage, nCall * 500, image, imageNode, imageNodeIdentifier, remoteImageId, nCall); } /** From 9c4751da0324b6901c33e95ab33dd7910a498948 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Thu, 3 Mar 2016 16:38:48 +0100 Subject: [PATCH 6/8] broken retries --- .../editor-common/assets/ZSSRichTextEditor.js | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index 5ce546c849f7..facdd768d6c8 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -937,10 +937,10 @@ ZSSEditor.replaceLocalImageWithRemoteImage = function(imageNodeIdentifier, remot ZSSEditor.finishLocalImageSwap = function(image, imageNode, imageNodeIdentifier, remoteImageId) { imageNode.addClass("wp-image-" + remoteImageId); if (image.getAttribute("remoteurl")) { - imageNode.attr('src', image.getAttribute("remoteurl")); - } else { - imageNode.attr('src', image.src); + imageNode.attr('remoteurl', image.getAttribute("remoteurl")); + console.log("FIXME: " + imageNode.attr('remoteurl')); } + imageNode.attr('src', image.src); ZSSEditor.markImageUploadDone(imageNodeIdentifier); var joinedArguments = ZSSEditor.getJoinedFocusedFieldIdAndCaretArguments(); ZSSEditor.callback("callback-input", joinedArguments); @@ -951,10 +951,10 @@ ZSSEditor.reloadImage = function(image, imageNode, imageNodeIdentifier, remoteIm if (image.classList.contains("image-loaded")) { return; } - console.log("Reloading image:" + nCall + " - " + image.src); image.onerror = ZSSEditor.tryToReload(image, imageNode, imageNodeIdentifier, remoteImageId, nCall + 1); // Force reloading by updating image src - image.src = image.getAttribute("remoteurl"); + image.src = image.getAttribute("remoteurl") + "?retry=" + nCall; + console.log("Reloading image:" + nCall + " - " + image.src); } ZSSEditor.tryToReload = function (image, imageNode, imageNodeIdentifier, remoteImageId, nCall) { @@ -1018,8 +1018,9 @@ ZSSEditor.markImageUploadDone = function(imageNodeIdentifier) { imageNode.parent().replaceWith(imageNode); } // Wrap link around image - var linkTag = ''; - imageNode.wrap(linkTag); + console.log("FIXME: " + imageNode.attr("src")); + var link = $('', { href: imageNode.attr("src") } ); + imageNode.wrap(link); // We invoke the sendImageReplacedCallback with a delay to avoid for // it to be ignored by the webview because of the previous callback being done. var thisObj = this; @@ -1657,6 +1658,25 @@ ZSSEditor.removeImageSelectionFormattingFromHTML = function( html ) { return tmpDom.html(); } +ZSSEditor.removeImageRemoteUrl = function( html ) { + var tmp = document.createElement( "div" ); + var tmpDom = $( tmp ).html( html ); + + var matches = tmpDom.find( "img" ); + if ( matches.length == 0 ) { + return html; + } + + for ( var i = 0; i < matches.length; i++ ) { + if (matches[i].getAttribute('remoteurl')) { + matches[i].src = matches[i].getAttribute('remoteurl'); + matches[i].removeAttribute('remoteurl'); + } + } + + return tmpDom.html(); +} + /** * @brief Finds all related caption nodes for the specified image node. * @@ -2097,6 +2117,7 @@ ZSSEditor.applyVisualFormatting = function( html ) { */ ZSSEditor.removeVisualFormatting = function( html ) { var str = html; + str = ZSSEditor.removeImageRemoteUrl( str ); str = ZSSEditor.removeImageSelectionFormattingFromHTML( str ); str = ZSSEditor.removeCaptionFormatting( str ); str = ZSSEditor.replaceVideoPressVideosForShortcode( str ); From 7955068690d1e18a092f945538e510ea39d07ee3 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Tue, 22 Mar 2016 14:38:06 +0100 Subject: [PATCH 7/8] Use remoteurl in the link wrapper --- .../editor-common/assets/ZSSRichTextEditor.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index facdd768d6c8..ec1527deaf46 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -1658,17 +1658,20 @@ ZSSEditor.removeImageSelectionFormattingFromHTML = function( html ) { return tmpDom.html(); } -ZSSEditor.removeImageRemoteUrl = function( html ) { - var tmp = document.createElement( "div" ); - var tmpDom = $( tmp ).html( html ); +ZSSEditor.removeImageRemoteUrl = function(html) { + var tmp = document.createElement("div"); + var tmpDom = $(tmp).html(html); - var matches = tmpDom.find( "img" ); - if ( matches.length == 0 ) { + var matches = tmpDom.find("img"); + if (matches.length == 0) { return html; } - for ( var i = 0; i < matches.length; i++ ) { + for (var i = 0; i < matches.length; i++) { if (matches[i].getAttribute('remoteurl')) { + if (matches[i].parentNode && matches[i].parentNode.href === matches[i].src) { + matches[i].parentNode.href = matches[i].getAttribute('remoteurl') + } matches[i].src = matches[i].getAttribute('remoteurl'); matches[i].removeAttribute('remoteurl'); } From 68a7ca7dc5a5db4f12de02bebcb7e73d1c986838 Mon Sep 17 00:00:00 2001 From: Maxime Biais Date: Tue, 22 Mar 2016 14:43:27 +0100 Subject: [PATCH 8/8] remove debug logs --- libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js index ec1527deaf46..d8b14e811d44 100755 --- a/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js +++ b/libs/editor/libs/editor-common/assets/ZSSRichTextEditor.js @@ -938,7 +938,6 @@ ZSSEditor.finishLocalImageSwap = function(image, imageNode, imageNodeIdentifier, imageNode.addClass("wp-image-" + remoteImageId); if (image.getAttribute("remoteurl")) { imageNode.attr('remoteurl', image.getAttribute("remoteurl")); - console.log("FIXME: " + imageNode.attr('remoteurl')); } imageNode.attr('src', image.src); ZSSEditor.markImageUploadDone(imageNodeIdentifier); @@ -1018,7 +1017,6 @@ ZSSEditor.markImageUploadDone = function(imageNodeIdentifier) { imageNode.parent().replaceWith(imageNode); } // Wrap link around image - console.log("FIXME: " + imageNode.attr("src")); var link = $('', { href: imageNode.attr("src") } ); imageNode.wrap(link); // We invoke the sendImageReplacedCallback with a delay to avoid for