From 7763e231a912acb5df93814deea32fbef877d604 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Sat, 26 Jan 2019 04:37:00 +0200 Subject: [PATCH 01/25] Update mPost via a method to update GB flag too --- .../android/ui/posts/EditPostActivity.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 0f91c8503b2a..596d148c2b40 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -276,7 +276,9 @@ enum AddExistingdMediaSource { */ WPViewPager mViewPager; + // don't set this directly. Use updatePostVar() to set it. private PostModel mPost; + private PostModel mPostForUndo; private PostModel mOriginalPost; private boolean mOriginalPostHadLocalChangesOnOpen; @@ -328,6 +330,12 @@ private boolean isModernEditor() { return mShowNewEditor || mShowAztecEditor || mShowGutenbergEditor; } + private void updatePostVar(PostModel postModel) { + mPost = postModel; + + mShowGutenbergEditor = PostUtils.shouldShowGutenbergEditor(mIsNewPost, mPost); + } + private Runnable mFetchMediaRunnable = new Runnable() { @Override public void run() { @@ -409,14 +417,14 @@ protected void onCreate(Bundle savedInstanceState) { } // Create a new post - mPost = mPostStore.instantiatePostModel(mSite, mIsPage, null, null); + updatePostVar(mPostStore.instantiatePostModel(mSite, mIsPage, null, null)); mPost.setStatus(PostStatus.PUBLISHED.toString()); EventBus.getDefault().postSticky( new PostEvents.PostOpenedInEditor(mPost.getLocalSiteId(), mPost.getId())); mShortcutUtils.reportShortcutUsed(Shortcut.CREATE_NEW_POST); } else if (extras != null) { // Load post passed in extras - mPost = mPostStore.getPostByLocalPostId(extras.getInt(EXTRA_POST_LOCAL_ID)); + updatePostVar(mPostStore.getPostByLocalPostId(extras.getInt(EXTRA_POST_LOCAL_ID))); if (mPost != null) { initializePostObject(); } @@ -433,10 +441,10 @@ protected void onCreate(Bundle savedInstanceState) { // if we have a remote id saved, let's first try with that, as the local Id might have changed // after FETCH_POSTS if (savedInstanceState.containsKey(STATE_KEY_POST_REMOTE_ID)) { - mPost = mPostStore.getPostByRemotePostId(savedInstanceState.getLong(STATE_KEY_POST_REMOTE_ID), mSite); + updatePostVar(mPostStore.getPostByRemotePostId(savedInstanceState.getLong(STATE_KEY_POST_REMOTE_ID), mSite)); initializePostObject(); } else if (savedInstanceState.containsKey(STATE_KEY_POST_LOCAL_ID)) { - mPost = mPostStore.getPostByLocalPostId(savedInstanceState.getInt(STATE_KEY_POST_LOCAL_ID)); + updatePostVar(mPostStore.getPostByLocalPostId(savedInstanceState.getInt(STATE_KEY_POST_LOCAL_ID))); initializePostObject(); } @@ -460,9 +468,6 @@ protected void onCreate(Bundle savedInstanceState) { mEditorFragment.setImageLoader(mImageLoader); } - // Ensure that this check happens when mPost is set - mShowGutenbergEditor = PostUtils.shouldShowGutenbergEditor(mIsNewPost, mPost); - // Ensure we have a valid post if (mPost == null) { showErrorAndFinish(R.string.post_not_found); @@ -537,7 +542,7 @@ private void initializePostObject() { if (mPost != null) { mOriginalPost = mPost.clone(); mOriginalPostHadLocalChangesOnOpen = mOriginalPost.isLocallyChanged(); - mPost = UploadService.updatePostWithCurrentlyCompletedUploads(mPost); + updatePostVar(UploadService.updatePostWithCurrentlyCompletedUploads(mPost)); if (mShowAztecEditor) { mMediaMarkedUploadingOnStartIds = AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, mPost.getContent()); @@ -1681,7 +1686,7 @@ public void onClick(View view) { AnalyticsTracker.track(Stat.REVISIONS_LOAD_UNDONE); RemotePostPayload payload = new RemotePostPayload(mPostForUndo, mSite); mDispatcher.dispatch(PostActionBuilder.newFetchPostAction(payload)); - mPost = mPostForUndo.clone(); + updatePostVar(mPostForUndo.clone()); refreshEditorContent(); } }) @@ -3673,7 +3678,7 @@ public void onPostChanged(OnPostChanged event) { if (mIsUpdatingPost) { mIsUpdatingPost = false; - mPost = mPostStore.getPostByLocalPostId(mPost.getId()); + updatePostVar(mPostStore.getPostByLocalPostId(mPost.getId())); refreshEditorContent(); if (mViewPager != null) { @@ -3684,7 +3689,7 @@ public void onPostChanged(OnPostChanged event) { AnalyticsTracker.track(Stat.EDITOR_DISCARDED_CHANGES_UNDO); RemotePostPayload payload = new RemotePostPayload(mPostForUndo, mSite); mDispatcher.dispatch(PostActionBuilder.newFetchPostAction(payload)); - mPost = mPostForUndo.clone(); + updatePostVar(mPostForUndo.clone()); refreshEditorContent(); } }) @@ -3696,7 +3701,7 @@ public void onPostChanged(OnPostChanged event) { if (mIsDiscardingChanges) { mIsDiscardingChanges = false; - mPost = mPostStore.getPostByLocalPostId(mPost.getId()); + updatePostVar(mPostStore.getPostByLocalPostId(mPost.getId())); mDispatcher.dispatch(PostActionBuilder.newUpdatePostAction(mPost)); mIsUpdatingPost = true; } @@ -3724,7 +3729,7 @@ public void onPostUploaded(OnPostUploaded event) { UploadUtils.onPostUploadedSnackbarHandler(this, snackbarAttachView, event.isError(), post, event.isError() ? event.error.message : null, getSite(), mDispatcher); if (!event.isError()) { - mPost = post; + updatePostVar(post); mIsNewPost = false; invalidateOptionsMenu(); } From e641b66cf74254e2b8221a6805a11d984f45fd52 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Sat, 26 Jan 2019 04:42:37 +0200 Subject: [PATCH 02/25] Cache the Spanned mPost for speed --- .../android/ui/posts/EditPostActivity.java | 28 +++++++++++--- .../android/ui/uploads/UploadService.java | 3 +- .../android/editor/AztecEditorFragment.java | 38 +++++++++---------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 596d148c2b40..76fb3ce1acc3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -538,6 +538,20 @@ public void run() { ActivityId.trackLastActivity(ActivityId.POST_EDITOR); } + private Spanned mCachedSpannedContent = new SpannableStringBuilder(""); + private int mCachedSpannedContentPostHashCode = 0; + + private @NonNull Spanned parsePostContent(Context context) { + if (mPost.hashCode() == mCachedSpannedContentPostHashCode) { + return mCachedSpannedContent; + } + + mCachedSpannedContent = AztecEditorFragment.parseContent(context, mPost.getContent()); + mCachedSpannedContentPostHashCode = mPost.hashCode(); + + return mCachedSpannedContent; + } + private void initializePostObject() { if (mPost != null) { mOriginalPost = mPost.clone(); @@ -545,7 +559,7 @@ private void initializePostObject() { updatePostVar(UploadService.updatePostWithCurrentlyCompletedUploads(mPost)); if (mShowAztecEditor) { mMediaMarkedUploadingOnStartIds = - AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, mPost.getContent()); + AztecEditorFragment.getMediaMarkedUploadingInPostContent(parsePostContent(this)); Collections.sort(mMediaMarkedUploadingOnStartIds); } mIsPage = mPost.isPage(); @@ -605,9 +619,9 @@ private void resetUploadingMediaToFailedIfPostHasNotMediaInProgressOrQueued() { } String oldContent = mPost.getContent(); - if (!AztecEditorFragment.hasMediaItemsMarkedUploading(this, oldContent) + if (!AztecEditorFragment.hasMediaItemsMarkedUploading(AztecEditorFragment.parseContent(this, oldContent)) // we need to make sure items marked failed are still failed or not as well - && !AztecEditorFragment.hasMediaItemsMarkedFailed(this, oldContent)) { + && !AztecEditorFragment.hasMediaItemsMarkedFailed(AztecEditorFragment.parseContent(this, oldContent))) { return; } @@ -1652,7 +1666,7 @@ private synchronized void savePostToDb() { if (mShowAztecEditor) { // update the list of uploading ids mMediaMarkedUploadingOnStartIds = - AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, mPost.getContent()); + AztecEditorFragment.getMediaMarkedUploadingInPostContent(parsePostContent(this)); } } @@ -2481,7 +2495,8 @@ private boolean isCurrentMediaMarkedUploadingDifferentToOriginal(String newConte if (!mShowAztecEditor) { return false; } - List currentUploadingMedia = AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, newContent); + List currentUploadingMedia = AztecEditorFragment.getMediaMarkedUploadingInPostContent( + AztecEditorFragment.parseContent(this, newContent)); Collections.sort(currentUploadingMedia); return !mMediaMarkedUploadingOnStartIds.equals(currentUploadingMedia); } @@ -3390,7 +3405,8 @@ public void onUndoMediaCheck(final String undoedContent) { List currentlyUploadingMedia = UploadService.getPendingOrInProgressMediaUploadsForPost(mPost); List mediaMarkedUploading = - AztecEditorFragment.getMediaMarkedUploadingInPostContent(EditPostActivity.this, undoedContent); + AztecEditorFragment.getMediaMarkedUploadingInPostContent( + AztecEditorFragment.parseContent(EditPostActivity.this, undoedContent)); // go through the list of items marked UPLOADING within the Post content, and look in the UploadService // to see whether they're really being uploaded or not. If an item is not really being uploaded, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java index 2972c8e9d7a4..9d7f35f56af7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java @@ -716,7 +716,8 @@ private void aztecRegisterFailedMediaForThisPost(PostModel post) { // the editor, and such media failed _before_ exiting the eidtor, thus the registration never happened. // We're recovering the information here so we make sure to rebuild the status only when the user taps // on Retry. - List mediaIds = AztecEditorFragment.getMediaMarkedFailedInPostContent(this, post.getContent()); + List mediaIds = AztecEditorFragment.getMediaMarkedFailedInPostContent( + AztecEditorFragment.parseContent(this, post.getContent())); if (mediaIds != null && !mediaIds.isEmpty()) { ArrayList mediaList = new ArrayList<>(); diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 351bb75ea634..91a05b40af3e 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -2091,24 +2091,20 @@ public static boolean isMediaInPostBody(Context context, @NonNull String postCon return (firstElementAttributes != null); } - public static boolean hasMediaItemsMarkedUploading(Context context, @NonNull String postContent) { - return hasMediaItemsMarkedWithTag(context, postContent, ATTR_STATUS_UPLOADING); + public static boolean hasMediaItemsMarkedUploading(@NonNull Spanned spannedContent) { + return hasMediaItemsMarkedWithTag(spannedContent, ATTR_STATUS_UPLOADING); } - public static boolean hasMediaItemsMarkedFailed(Context context, @NonNull String postContent) { - return hasMediaItemsMarkedWithTag(context, postContent, ATTR_STATUS_FAILED); + public static boolean hasMediaItemsMarkedFailed(@NonNull Spanned spannedContent) { + return hasMediaItemsMarkedWithTag(spannedContent, ATTR_STATUS_FAILED); } - private static boolean hasMediaItemsMarkedWithTag(Context context, @NonNull String postContent, String tag) { - // fill in Aztec with the post's content - AztecParser parser = getAztecParserWithPlugins(); - Spanned content = parser.fromHtml(postContent, context); - + private static boolean hasMediaItemsMarkedWithTag(@NonNull Spanned spannedContent, String tag) { // get all items with the class in the "tag" param AztecText.AttributePredicate uploadingPredicate = getPredicateWithClass(tag); - return getFirstElementAttributes(content, uploadingPredicate) != null; + return getFirstElementAttributes(spannedContent, uploadingPredicate) != null; } public static String resetUploadingMediaToFailed(Context context, @NonNull String postContent) { @@ -2128,22 +2124,18 @@ public static String resetUploadingMediaToFailed(Context context, @NonNull Strin return postContent; } - public static List getMediaMarkedUploadingInPostContent(Context context, @NonNull String postContent) { - return getMediaMarkedAsClassInPostContent(context, postContent, ATTR_STATUS_UPLOADING); + public static List getMediaMarkedUploadingInPostContent(@NonNull Spanned spannedContent) { + return getMediaMarkedAsClassInPostContent(spannedContent, ATTR_STATUS_UPLOADING); } - public static List getMediaMarkedFailedInPostContent(Context context, @NonNull String postContent) { - return getMediaMarkedAsClassInPostContent(context, postContent, ATTR_STATUS_FAILED); + public static List getMediaMarkedFailedInPostContent(@NonNull Spanned spannedContent) { + return getMediaMarkedAsClassInPostContent(spannedContent, ATTR_STATUS_FAILED); } - private static List getMediaMarkedAsClassInPostContent(Context context, @NonNull String postContent, - String classToUse) { + private static List getMediaMarkedAsClassInPostContent(@NonNull Spanned spannedContent, String classToUse) { ArrayList mediaMarkedUploading = new ArrayList<>(); - // fill in Aztec with the post's content - AztecParser parser = getAztecParserWithPlugins(); - Spanned content = parser.fromHtml(postContent, context); AztecText.AttributePredicate uploadingPredicate = getPredicateWithClass(classToUse); - for (Attributes attrs : getAllElementAttributes(content, uploadingPredicate)) { + for (Attributes attrs : getAllElementAttributes(spannedContent, uploadingPredicate)) { String itemId = attrs.getValue(ATTR_ID_WP); if (!TextUtils.isEmpty(itemId)) { mediaMarkedUploading.add(itemId); @@ -2152,6 +2144,12 @@ private static List getMediaMarkedAsClassInPostContent(Context context, return mediaMarkedUploading; } + public static Spanned parseContent(Context context, @NonNull String postContent) { + // fill in Aztec with the post's content + AztecParser parser = getAztecParserWithPlugins(); + return parser.fromHtml(postContent, context); + } + public void setMediaToFailed(@NonNull String mediaId) { AztecText.AttributePredicate localMediaIdPredicate = MediaPredicate.getLocalMediaIdPredicate(mediaId); // we should be obtaining just one span for this media Id predicate, but just in case something From 722dd8c7dfab20d860ed59cc16ccd891fc115765 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Feb 2019 03:08:39 +0200 Subject: [PATCH 03/25] Use fast Aztec parsing when appropriate The full parsing involves adjusting the visual newlines, and that is a costly operation (according to the profiler). When we can, we can use the the fast parsing variant. --- .../org/wordpress/android/editor/AztecEditorFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 91a05b40af3e..8d9657d22e84 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -1987,7 +1987,7 @@ private static SpannableStringBuilder getCalypsoCompatibleStringBuilder(Context AztecParser parser) { SpannableStringBuilder builder = new SpannableStringBuilder(); String cleanSource = Format.removeSourceEditorFormatting(postContent, true); - builder.append(parser.fromHtml(cleanSource, context)); + builder.append(parser.parseHtmlForInspection(cleanSource, context)); Format.preProcessSpannedText(builder, true); return builder; } @@ -2147,7 +2147,7 @@ private static List getMediaMarkedAsClassInPostContent(@NonNull Spanned public static Spanned parseContent(Context context, @NonNull String postContent) { // fill in Aztec with the post's content AztecParser parser = getAztecParserWithPlugins(); - return parser.fromHtml(postContent, context); + return parser.parseHtmlForInspection(postContent, context); } public void setMediaToFailed(@NonNull String mediaId) { From c6fdcd63a4d48eae3cb05f74e9f8d450bb55589d Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Feb 2019 03:36:09 +0200 Subject: [PATCH 04/25] Point to faster Aztec, update gb-mobile ref too --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index aebae4ecbe2b..27f76614e79b 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = 'd2f24f4a7c21e2be77ef77cd646e67a3a2b9802a' + aztecVersion = '4d461f5a889a6b1c147e7abd2a64456966bbc3f6' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 9dce6adba88c..0582a442b8b7 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 9dce6adba88cc2fd9a5480fa020bb23fb0c620e7 +Subproject commit 0582a442b8b7a329a90a939c50c2a936a6c444f8 From 4f82a72991ca489400e3aa34e8c89784f2d9da4a Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Fri, 1 Mar 2019 18:45:30 +0100 Subject: [PATCH 05/25] Update Aztec, gb-mobile refs --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index 27f76614e79b..f7e6f1055974 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = '4d461f5a889a6b1c147e7abd2a64456966bbc3f6' + aztecVersion = 'b3bd20cdd793868f0cedb119d03231379dda585c' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 0582a442b8b7..53b675f7d85e 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 0582a442b8b7a329a90a939c50c2a936a6c444f8 +Subproject commit 53b675f7d85e1516facf5064d196dd8fee12e979 From bc7615effa821393e545b4bf1147e221f8efafa9 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 11:07:56 +0200 Subject: [PATCH 06/25] 1-deep cache of parsed content --- .../android/editor/AztecEditorFragment.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 8d9657d22e84..d8bcbf64a98b 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -2144,10 +2144,22 @@ private static List getMediaMarkedAsClassInPostContent(@NonNull Spanned return mediaMarkedUploading; } + private static int sPostContentHash; + private static Spanned sParsedContentCached; + public static Spanned parseContent(Context context, @NonNull String postContent) { + // parsing is an expensive operation (especially if the content is big) so, return previous result if matching. + if (sParsedContentCached != null && postContent.hashCode() == sPostContentHash) { + return new SpannableString(sParsedContentCached); + } + + // cache the post's content hash to compare next time + sPostContentHash = postContent.hashCode(); + // fill in Aztec with the post's content AztecParser parser = getAztecParserWithPlugins(); - return parser.parseHtmlForInspection(postContent, context); + sParsedContentCached = parser.parseHtmlForInspection(postContent, context); + return sParsedContentCached; } public void setMediaToFailed(@NonNull String mediaId) { From 99244f80214ded135138f565c5ae99780f9144a6 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 11:48:57 +0200 Subject: [PATCH 07/25] Update gb-mobile ref --- libs/gutenberg-mobile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 53b675f7d85e..821bb334af57 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 53b675f7d85e1516facf5064d196dd8fee12e979 +Subproject commit 821bb334af577f865649aa0154e805160e89cb09 From 85c060f44179a3f3ba7ea2aa28cf1c52da8d993e Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 11:49:59 +0200 Subject: [PATCH 08/25] Update Aztec ref --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index 4cb01cd3ddc0..a0bd9585369b 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = 'b3bd20cdd793868f0cedb119d03231379dda585c' + aztecVersion = '7112c2074487002c71b12a07be39a8c0a8369301' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 821bb334af57..e01055131664 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 821bb334af577f865649aa0154e805160e89cb09 +Subproject commit e01055131664ff35f273bc61b642d62076612e56 From e9f7d0c9cc6461253336c6539bc9886d27b0920a Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 14:03:10 +0200 Subject: [PATCH 09/25] Update Aztec hash --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index a0bd9585369b..1f54d6eaa1d1 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = '7112c2074487002c71b12a07be39a8c0a8369301' + aztecVersion = '3c1b41f4bbd3c9697c5deafaea54814f83b1907d' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index e01055131664..0d60b1041c63 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit e01055131664ff35f273bc61b642d62076612e56 +Subproject commit 0d60b1041c63b20f3999a87be54ebe44348707c7 From 25df6edad3f77619aca2538ba3374e487a194343 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 14:18:34 +0200 Subject: [PATCH 10/25] Update Aztec hash --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index 1f54d6eaa1d1..bfe4de3f174c 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = '3c1b41f4bbd3c9697c5deafaea54814f83b1907d' + aztecVersion = 'bd1c9fa37ff5f332720186c3f5d1dee5f4e0944d' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 0d60b1041c63..a411c3bc02f1 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 0d60b1041c63b20f3999a87be54ebe44348707c7 +Subproject commit a411c3bc02f189ec07e260143bb8cfed9c60ce72 From 48b66cf51a7647220543ae28a9721c99784ca5e3 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 15:00:32 +0200 Subject: [PATCH 11/25] Compare the content's hash, not the post's --- .../android/ui/posts/EditPostActivity.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 75e99b377c08..e204355aa44c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -344,6 +344,10 @@ enum RestartEditorOptions { // for keeping the media uri while asking for permissions private ArrayList mDroppedMediaUris; + // 1-deep cache of parsed html string for optimizing the repeated attempts to parse the same content again and again + private Spanned mCachedSpannedContent = new SpannableStringBuilder(""); + private int mCachedSpannedContentHashCode = 0; + private boolean isModernEditor() { return mShowNewEditor || mShowAztecEditor || mShowGutenbergEditor; } @@ -605,16 +609,16 @@ public void run() { ActivityId.trackLastActivity(ActivityId.POST_EDITOR); } - private Spanned mCachedSpannedContent = new SpannableStringBuilder(""); - private int mCachedSpannedContentPostHashCode = 0; - private @NonNull Spanned parsePostContent(Context context) { - if (mPost.hashCode() == mCachedSpannedContentPostHashCode) { + final String content = mPost.getContent(); + final int hashCode = content.hashCode(); + + if (hashCode == mCachedSpannedContentHashCode) { return mCachedSpannedContent; } - mCachedSpannedContent = AztecEditorFragment.parseContent(context, mPost.getContent()); - mCachedSpannedContentPostHashCode = mPost.hashCode(); + mCachedSpannedContent = AztecEditorFragment.parseContent(context, content); + mCachedSpannedContentHashCode = hashCode; return mCachedSpannedContent; } From fbc89abb60fcc6ed84165b24c29c219b181f643b Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 15:21:55 +0200 Subject: [PATCH 12/25] Limit line to 120chars --- .../java/org/wordpress/android/ui/posts/EditPostActivity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index e204355aa44c..73e6e280d97e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -489,7 +489,8 @@ protected void onCreate(Bundle savedInstanceState) { // if we have a remote id saved, let's first try that, as the local Id might have changed after FETCH_POSTS if (savedInstanceState.containsKey(STATE_KEY_POST_REMOTE_ID)) { - updatePostVar(mPostStore.getPostByRemotePostId(savedInstanceState.getLong(STATE_KEY_POST_REMOTE_ID), mSite)); + updatePostVar( + mPostStore.getPostByRemotePostId(savedInstanceState.getLong(STATE_KEY_POST_REMOTE_ID), mSite)); initializePostObject(); } else if (savedInstanceState.containsKey(STATE_KEY_POST_LOCAL_ID)) { updatePostVar(mPostStore.getPostByLocalPostId(savedInstanceState.getInt(STATE_KEY_POST_LOCAL_ID))); From c7eca95d3bee391fc5dc3bb2168fda5edf9473ff Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 15:22:25 +0200 Subject: [PATCH 13/25] No need for the 1-deep cache in EditPostActivity --- .../android/ui/posts/EditPostActivity.java | 26 +++---------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 73e6e280d97e..83734aaf669d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -344,10 +344,6 @@ enum RestartEditorOptions { // for keeping the media uri while asking for permissions private ArrayList mDroppedMediaUris; - // 1-deep cache of parsed html string for optimizing the repeated attempts to parse the same content again and again - private Spanned mCachedSpannedContent = new SpannableStringBuilder(""); - private int mCachedSpannedContentHashCode = 0; - private boolean isModernEditor() { return mShowNewEditor || mShowAztecEditor || mShowGutenbergEditor; } @@ -610,28 +606,14 @@ public void run() { ActivityId.trackLastActivity(ActivityId.POST_EDITOR); } - private @NonNull Spanned parsePostContent(Context context) { - final String content = mPost.getContent(); - final int hashCode = content.hashCode(); - - if (hashCode == mCachedSpannedContentHashCode) { - return mCachedSpannedContent; - } - - mCachedSpannedContent = AztecEditorFragment.parseContent(context, content); - mCachedSpannedContentHashCode = hashCode; - - return mCachedSpannedContent; - } - private void initializePostObject() { if (mPost != null) { mOriginalPost = mPost.clone(); mOriginalPostHadLocalChangesOnOpen = mOriginalPost.isLocallyChanged(); updatePostVar(UploadService.updatePostWithCurrentlyCompletedUploads(mPost)); if (mShowAztecEditor) { - mMediaMarkedUploadingOnStartIds = - AztecEditorFragment.getMediaMarkedUploadingInPostContent(parsePostContent(this)); + mMediaMarkedUploadingOnStartIds = AztecEditorFragment.getMediaMarkedUploadingInPostContent( + AztecEditorFragment.parseContent(this, mPost.getContent())); Collections.sort(mMediaMarkedUploadingOnStartIds); } mIsPage = mPost.isPage(); @@ -1815,8 +1797,8 @@ private synchronized void savePostToDb() { if (mShowAztecEditor) { // update the list of uploading ids - mMediaMarkedUploadingOnStartIds = - AztecEditorFragment.getMediaMarkedUploadingInPostContent(parsePostContent(this)); + mMediaMarkedUploadingOnStartIds = AztecEditorFragment.getMediaMarkedUploadingInPostContent( + AztecEditorFragment.parseContent(this, mPost.getContent())); } } From f2bdaf70cea42664bf5120ff146a48ff4853858e Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 15:36:17 +0200 Subject: [PATCH 14/25] No need for updatePostVar --- .../android/ui/posts/EditPostActivity.java | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 83734aaf669d..fa22fc31d200 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -348,12 +348,6 @@ private boolean isModernEditor() { return mShowNewEditor || mShowAztecEditor || mShowGutenbergEditor; } - private void updatePostVar(PostModel postModel) { - mPost = postModel; - - mShowGutenbergEditor = PostUtils.shouldShowGutenbergEditor(mIsNewPost, mPost); - } - private Runnable mFetchMediaRunnable = new Runnable() { @Override public void run() { @@ -458,7 +452,7 @@ protected void onCreate(Bundle savedInstanceState) { } newPostSetup(); } else if (extras != null) { - updatePostVar(mPostStore.getPostByLocalPostId(extras.getInt(EXTRA_POST_LOCAL_ID))); + mPost = mPostStore.getPostByLocalPostId(extras.getInt(EXTRA_POST_LOCAL_ID)); if (mPost != null) { initializePostObject(); @@ -485,11 +479,10 @@ protected void onCreate(Bundle savedInstanceState) { // if we have a remote id saved, let's first try that, as the local Id might have changed after FETCH_POSTS if (savedInstanceState.containsKey(STATE_KEY_POST_REMOTE_ID)) { - updatePostVar( - mPostStore.getPostByRemotePostId(savedInstanceState.getLong(STATE_KEY_POST_REMOTE_ID), mSite)); + mPost = mPostStore.getPostByRemotePostId(savedInstanceState.getLong(STATE_KEY_POST_REMOTE_ID), mSite); initializePostObject(); } else if (savedInstanceState.containsKey(STATE_KEY_POST_LOCAL_ID)) { - updatePostVar(mPostStore.getPostByLocalPostId(savedInstanceState.getInt(STATE_KEY_POST_LOCAL_ID))); + mPost = mPostStore.getPostByLocalPostId(savedInstanceState.getInt(STATE_KEY_POST_LOCAL_ID)); initializePostObject(); } @@ -610,7 +603,7 @@ private void initializePostObject() { if (mPost != null) { mOriginalPost = mPost.clone(); mOriginalPostHadLocalChangesOnOpen = mOriginalPost.isLocallyChanged(); - updatePostVar(UploadService.updatePostWithCurrentlyCompletedUploads(mPost)); + mPost = UploadService.updatePostWithCurrentlyCompletedUploads(mPost); if (mShowAztecEditor) { mMediaMarkedUploadingOnStartIds = AztecEditorFragment.getMediaMarkedUploadingInPostContent( AztecEditorFragment.parseContent(this, mPost.getContent())); @@ -1832,7 +1825,7 @@ public void onClick(View view) { AnalyticsTracker.track(Stat.REVISIONS_LOAD_UNDONE); RemotePostPayload payload = new RemotePostPayload(mPostForUndo, mSite); mDispatcher.dispatch(PostActionBuilder.newFetchPostAction(payload)); - updatePostVar(mPostForUndo.clone()); + mPost = mPostForUndo.clone(); refreshEditorContent(); } }) @@ -3849,7 +3842,7 @@ public void onPostChanged(OnPostChanged event) { if (mIsUpdatingPost) { mIsUpdatingPost = false; - updatePostVar(mPostStore.getPostByLocalPostId(mPost.getId())); + mPost = mPostStore.getPostByLocalPostId(mPost.getId()); refreshEditorContent(); if (mViewPager != null) { @@ -3860,7 +3853,7 @@ public void onPostChanged(OnPostChanged event) { AnalyticsTracker.track(Stat.EDITOR_DISCARDED_CHANGES_UNDO); RemotePostPayload payload = new RemotePostPayload(mPostForUndo, mSite); mDispatcher.dispatch(PostActionBuilder.newFetchPostAction(payload)); - updatePostVar(mPostForUndo.clone()); + mPost = mPostForUndo.clone(); refreshEditorContent(); } }) @@ -3872,7 +3865,7 @@ public void onPostChanged(OnPostChanged event) { if (mIsDiscardingChanges) { mIsDiscardingChanges = false; - updatePostVar(mPostStore.getPostByLocalPostId(mPost.getId())); + mPost = mPostStore.getPostByLocalPostId(mPost.getId()); mDispatcher.dispatch(PostActionBuilder.newUpdatePostAction(mPost)); mIsUpdatingPost = true; } @@ -3900,7 +3893,7 @@ public void onPostUploaded(OnPostUploaded event) { UploadUtils.onPostUploadedSnackbarHandler(this, snackbarAttachView, event.isError(), post, event.isError() ? event.error.message : null, getSite(), mDispatcher); if (!event.isError()) { - updatePostVar(post); + mPost = post; mIsNewPost = false; invalidateOptionsMenu(); } From 8c7a0e9964dc9576d871926fae9039dd2c749aa5 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 15:46:43 +0200 Subject: [PATCH 15/25] Some cleanup --- .../java/org/wordpress/android/ui/posts/EditPostActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index fa22fc31d200..0a6087f0f69e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -294,9 +294,7 @@ enum RestartEditorOptions { */ WPViewPager mViewPager; - // don't set this directly. Use updatePostVar() to set it. private PostModel mPost; - private PostModel mPostForUndo; private PostModel mOriginalPost; private boolean mOriginalPostHadLocalChangesOnOpen; @@ -452,7 +450,7 @@ protected void onCreate(Bundle savedInstanceState) { } newPostSetup(); } else if (extras != null) { - mPost = mPostStore.getPostByLocalPostId(extras.getInt(EXTRA_POST_LOCAL_ID)); + mPost = mPostStore.getPostByLocalPostId(extras.getInt(EXTRA_POST_LOCAL_ID)); // Load post from extras if (mPost != null) { initializePostObject(); From 5f4376309e65defd8b7e6babc4b37b136a750cc0 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 16:22:32 +0200 Subject: [PATCH 16/25] Reinstate old interfaces, use parse cache in AztecEditorFragment --- .../android/ui/posts/EditPostActivity.java | 19 +++++++------- .../android/ui/uploads/UploadService.java | 3 +-- .../android/editor/AztecEditorFragment.java | 25 ++++++++++--------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 0a6087f0f69e..37d5d8a3fa0b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -603,8 +603,8 @@ private void initializePostObject() { mOriginalPostHadLocalChangesOnOpen = mOriginalPost.isLocallyChanged(); mPost = UploadService.updatePostWithCurrentlyCompletedUploads(mPost); if (mShowAztecEditor) { - mMediaMarkedUploadingOnStartIds = AztecEditorFragment.getMediaMarkedUploadingInPostContent( - AztecEditorFragment.parseContent(this, mPost.getContent())); + mMediaMarkedUploadingOnStartIds = + AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, mPost.getContent()); Collections.sort(mMediaMarkedUploadingOnStartIds); } mIsPage = mPost.isPage(); @@ -664,9 +664,9 @@ private void resetUploadingMediaToFailedIfPostHasNotMediaInProgressOrQueued() { } String oldContent = mPost.getContent(); - if (!AztecEditorFragment.hasMediaItemsMarkedUploading(AztecEditorFragment.parseContent(this, oldContent)) + if (!AztecEditorFragment.hasMediaItemsMarkedUploading(this, oldContent) // we need to make sure items marked failed are still failed or not as well - && !AztecEditorFragment.hasMediaItemsMarkedFailed(AztecEditorFragment.parseContent(this, oldContent))) { + && !AztecEditorFragment.hasMediaItemsMarkedFailed(this, oldContent)) { return; } @@ -1788,8 +1788,8 @@ private synchronized void savePostToDb() { if (mShowAztecEditor) { // update the list of uploading ids - mMediaMarkedUploadingOnStartIds = AztecEditorFragment.getMediaMarkedUploadingInPostContent( - AztecEditorFragment.parseContent(this, mPost.getContent())); + mMediaMarkedUploadingOnStartIds = + AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, mPost.getContent()); } } @@ -2634,8 +2634,8 @@ private boolean isCurrentMediaMarkedUploadingDifferentToOriginal(String newConte if (!mShowAztecEditor) { return false; } - List currentUploadingMedia = AztecEditorFragment.getMediaMarkedUploadingInPostContent( - AztecEditorFragment.parseContent(this, newContent)); + List currentUploadingMedia = + AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, newContent); Collections.sort(currentUploadingMedia); return !mMediaMarkedUploadingOnStartIds.equals(currentUploadingMedia); } @@ -3544,8 +3544,7 @@ public void onUndoMediaCheck(final String undoedContent) { List currentlyUploadingMedia = UploadService.getPendingOrInProgressMediaUploadsForPost(mPost); List mediaMarkedUploading = - AztecEditorFragment.getMediaMarkedUploadingInPostContent( - AztecEditorFragment.parseContent(EditPostActivity.this, undoedContent)); + AztecEditorFragment.getMediaMarkedUploadingInPostContent(EditPostActivity.this, undoedContent); // go through the list of items marked UPLOADING within the Post content, and look in the UploadService // to see whether they're really being uploaded or not. If an item is not really being uploaded, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java index 9d7f35f56af7..2972c8e9d7a4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadService.java @@ -716,8 +716,7 @@ private void aztecRegisterFailedMediaForThisPost(PostModel post) { // the editor, and such media failed _before_ exiting the eidtor, thus the registration never happened. // We're recovering the information here so we make sure to rebuild the status only when the user taps // on Retry. - List mediaIds = AztecEditorFragment.getMediaMarkedFailedInPostContent( - AztecEditorFragment.parseContent(this, post.getContent())); + List mediaIds = AztecEditorFragment.getMediaMarkedFailedInPostContent(this, post.getContent()); if (mediaIds != null && !mediaIds.isEmpty()) { ArrayList mediaList = new ArrayList<>(); diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index d8bcbf64a98b..5410125a09e2 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -2091,20 +2091,20 @@ public static boolean isMediaInPostBody(Context context, @NonNull String postCon return (firstElementAttributes != null); } - public static boolean hasMediaItemsMarkedUploading(@NonNull Spanned spannedContent) { - return hasMediaItemsMarkedWithTag(spannedContent, ATTR_STATUS_UPLOADING); + public static boolean hasMediaItemsMarkedUploading(Context context, @NonNull String postContent) { + return hasMediaItemsMarkedWithTag(context, postContent, ATTR_STATUS_UPLOADING); } - public static boolean hasMediaItemsMarkedFailed(@NonNull Spanned spannedContent) { - return hasMediaItemsMarkedWithTag(spannedContent, ATTR_STATUS_FAILED); + public static boolean hasMediaItemsMarkedFailed(Context context, @NonNull String postContent) { + return hasMediaItemsMarkedWithTag(context, postContent, ATTR_STATUS_FAILED); } - private static boolean hasMediaItemsMarkedWithTag(@NonNull Spanned spannedContent, String tag) { + private static boolean hasMediaItemsMarkedWithTag(Context context, @NonNull String postContent, String tag) { // get all items with the class in the "tag" param AztecText.AttributePredicate uploadingPredicate = getPredicateWithClass(tag); - return getFirstElementAttributes(spannedContent, uploadingPredicate) != null; + return getFirstElementAttributes(parseContent(context, postContent), uploadingPredicate) != null; } public static String resetUploadingMediaToFailed(Context context, @NonNull String postContent) { @@ -2124,18 +2124,19 @@ public static String resetUploadingMediaToFailed(Context context, @NonNull Strin return postContent; } - public static List getMediaMarkedUploadingInPostContent(@NonNull Spanned spannedContent) { - return getMediaMarkedAsClassInPostContent(spannedContent, ATTR_STATUS_UPLOADING); + public static List getMediaMarkedUploadingInPostContent(Context context, @NonNull String postContent) { + return getMediaMarkedAsClassInPostContent(context, postContent, ATTR_STATUS_UPLOADING); } - public static List getMediaMarkedFailedInPostContent(@NonNull Spanned spannedContent) { - return getMediaMarkedAsClassInPostContent(spannedContent, ATTR_STATUS_FAILED); + public static List getMediaMarkedFailedInPostContent(Context context, @NonNull String postContent) { + return getMediaMarkedAsClassInPostContent(context, postContent, ATTR_STATUS_FAILED); } - private static List getMediaMarkedAsClassInPostContent(@NonNull Spanned spannedContent, String classToUse) { + private static List getMediaMarkedAsClassInPostContent(Context context, @NonNull String postContent, + String classToUse) { ArrayList mediaMarkedUploading = new ArrayList<>(); AztecText.AttributePredicate uploadingPredicate = getPredicateWithClass(classToUse); - for (Attributes attrs : getAllElementAttributes(spannedContent, uploadingPredicate)) { + for (Attributes attrs : getAllElementAttributes(parseContent(context, postContent), uploadingPredicate)) { String itemId = attrs.getValue(ATTR_ID_WP); if (!TextUtils.isEmpty(itemId)) { mediaMarkedUploading.add(itemId); From b7dd5d585bb9b362458affdd7b4a0ee4366c1dfe Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 16:26:37 +0200 Subject: [PATCH 17/25] Reduce PR diff --- .../java/org/wordpress/android/ui/posts/EditPostActivity.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java index 37d5d8a3fa0b..64937991ce1d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java @@ -2634,8 +2634,7 @@ private boolean isCurrentMediaMarkedUploadingDifferentToOriginal(String newConte if (!mShowAztecEditor) { return false; } - List currentUploadingMedia = - AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, newContent); + List currentUploadingMedia = AztecEditorFragment.getMediaMarkedUploadingInPostContent(this, newContent); Collections.sort(currentUploadingMedia); return !mMediaMarkedUploadingOnStartIds.equals(currentUploadingMedia); } From a38544b06a37785cc9ef4a963b037742471ac839 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 16:33:28 +0200 Subject: [PATCH 18/25] Move instance variables to the top --- .../org/wordpress/android/editor/AztecEditorFragment.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 5410125a09e2..4d68b9b29ce3 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -154,6 +154,10 @@ public AztecLoggingException(Throwable originalException) { private static boolean mIsToolbarExpanded = false; + // 1-deep cache of html parsed to spans, as a speed optimization instead of parsing the same content again and again + private static int sPostContentHash; + private static Spanned sParsedContentCached; + private boolean mEditorWasPaused = false; private boolean mHideActionBarOnSoftKeyboardUp = false; @@ -2145,9 +2149,6 @@ private static List getMediaMarkedAsClassInPostContent(Context context, return mediaMarkedUploading; } - private static int sPostContentHash; - private static Spanned sParsedContentCached; - public static Spanned parseContent(Context context, @NonNull String postContent) { // parsing is an expensive operation (especially if the content is big) so, return previous result if matching. if (sParsedContentCached != null && postContent.hashCode() == sPostContentHash) { From 927cbd66143817814f57828953b8484c8141a17f Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 16:34:33 +0200 Subject: [PATCH 19/25] Less PR diff --- .../android/editor/AztecEditorFragment.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java index 4d68b9b29ce3..90b3f09fbd16 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/AztecEditorFragment.java @@ -2104,11 +2104,15 @@ public static boolean hasMediaItemsMarkedFailed(Context context, @NonNull String } private static boolean hasMediaItemsMarkedWithTag(Context context, @NonNull String postContent, String tag) { + // fill in Aztec with the post's content + AztecParser parser = getAztecParserWithPlugins(); + Spanned content = parseContent(context, parser, postContent); + // get all items with the class in the "tag" param AztecText.AttributePredicate uploadingPredicate = getPredicateWithClass(tag); - return getFirstElementAttributes(parseContent(context, postContent), uploadingPredicate) != null; + return getFirstElementAttributes(content, uploadingPredicate) != null; } public static String resetUploadingMediaToFailed(Context context, @NonNull String postContent) { @@ -2139,8 +2143,11 @@ public static List getMediaMarkedFailedInPostContent(Context context, @N private static List getMediaMarkedAsClassInPostContent(Context context, @NonNull String postContent, String classToUse) { ArrayList mediaMarkedUploading = new ArrayList<>(); + // fill in Aztec with the post's content + AztecParser parser = getAztecParserWithPlugins(); + Spanned content = parseContent(context, parser, postContent); AztecText.AttributePredicate uploadingPredicate = getPredicateWithClass(classToUse); - for (Attributes attrs : getAllElementAttributes(parseContent(context, postContent), uploadingPredicate)) { + for (Attributes attrs : getAllElementAttributes(content, uploadingPredicate)) { String itemId = attrs.getValue(ATTR_ID_WP); if (!TextUtils.isEmpty(itemId)) { mediaMarkedUploading.add(itemId); @@ -2149,7 +2156,7 @@ private static List getMediaMarkedAsClassInPostContent(Context context, return mediaMarkedUploading; } - public static Spanned parseContent(Context context, @NonNull String postContent) { + public static Spanned parseContent(Context context, AztecParser parser, @NonNull String postContent) { // parsing is an expensive operation (especially if the content is big) so, return previous result if matching. if (sParsedContentCached != null && postContent.hashCode() == sPostContentHash) { return new SpannableString(sParsedContentCached); @@ -2159,7 +2166,6 @@ public static Spanned parseContent(Context context, @NonNull String postContent) sPostContentHash = postContent.hashCode(); // fill in Aztec with the post's content - AztecParser parser = getAztecParserWithPlugins(); sParsedContentCached = parser.parseHtmlForInspection(postContent, context); return sParsedContentCached; } From 36599c4db79f926dded421b069164faffff61995 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 16:48:12 +0200 Subject: [PATCH 20/25] Update release notes --- RELEASE-NOTES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index ed942ed6357e..5d27bc5639a7 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,5 +1,6 @@ 12.0 ----- +Faster opening of large posts 11.9 ----- From 39adc35e6e732d7e32b3f2c73e2d229de6de909e Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 18:56:00 +0200 Subject: [PATCH 21/25] Progress bar while waiting for GB --- .../android/editor/GutenbergEditorFragment.java | 11 +++++++++++ .../src/main/res/layout/fragment_gutenberg_editor.xml | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java index 5da912661c4c..301495d6846b 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java @@ -9,6 +9,7 @@ import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.support.annotation.NonNull; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; @@ -240,6 +241,16 @@ public void onQueryCurrentProgressForUploadingMedia() { @Override public void onEditorDidMount(boolean hasUnsupportedBlocks) { mEditorFragmentListener.onEditorFragmentContentReady(hasUnsupportedBlocks); + + // Hide the progress bar when editor is ready + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + if (isAdded() && getView() != null) { + getView().findViewById(R.id.editor_progress).setVisibility(View.GONE); + } + } + }); } } ); diff --git a/libs/editor/WordPressEditor/src/main/res/layout/fragment_gutenberg_editor.xml b/libs/editor/WordPressEditor/src/main/res/layout/fragment_gutenberg_editor.xml index 28cf1027e77c..b499d654daba 100644 --- a/libs/editor/WordPressEditor/src/main/res/layout/fragment_gutenberg_editor.xml +++ b/libs/editor/WordPressEditor/src/main/res/layout/fragment_gutenberg_editor.xml @@ -5,4 +5,12 @@ android:layout_width="match_parent" android:background="@color/white" android:focusable="false" - android:focusableInTouchMode="true"/> + android:focusableInTouchMode="true"> + + + From 8db163b4a1079b33b91fdac4f3fb5ee27cfccd8b Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Mar 2019 19:36:21 +0200 Subject: [PATCH 22/25] Track the editor mount state, hide progress bar on rotate --- .../editor/GutenbergEditorFragment.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java index 301495d6846b..f5c87d4b4fd3 100644 --- a/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java +++ b/libs/editor/WordPressEditor/src/main/java/org/wordpress/android/editor/GutenbergEditorFragment.java @@ -56,6 +56,7 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements EditorMediaUploadListener, IHistoryListener { private static final String KEY_HTML_MODE_ENABLED = "KEY_HTML_MODE_ENABLED"; + private static final String KEY_EDITOR_DID_MOUNT = "KEY_EDITOR_DID_MOUNT"; private static final String ARG_IS_NEW_POST = "param_is_new_post"; private static final String ARG_LOCALE_SLUG = "param_locale_slug"; @@ -78,6 +79,8 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements private boolean mIsNewPost; + private boolean mEditorDidMount; + public static GutenbergEditorFragment newInstance(String title, String content, boolean isNewPost, @@ -194,6 +197,7 @@ public void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { mHtmlModeEnabled = savedInstanceState.getBoolean(KEY_HTML_MODE_ENABLED); + mEditorDidMount = savedInstanceState.getBoolean(KEY_EDITOR_DID_MOUNT); } } @@ -240,15 +244,14 @@ public void onQueryCurrentProgressForUploadingMedia() { new OnEditorMountListener() { @Override public void onEditorDidMount(boolean hasUnsupportedBlocks) { + mEditorDidMount = true; mEditorFragmentListener.onEditorFragmentContentReady(hasUnsupportedBlocks); // Hide the progress bar when editor is ready new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { - if (isAdded() && getView() != null) { - getView().findViewById(R.id.editor_progress).setVisibility(View.GONE); - } + setEditorProgressBarVisibility(!mEditorDidMount); } }); } @@ -284,6 +287,12 @@ public void run() { return view; } + @Override public void onResume() { + super.onResume(); + + setEditorProgressBarVisibility(!mEditorDidMount); + } + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { @@ -292,6 +301,12 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis } } + private void setEditorProgressBarVisibility(boolean shown) { + if (isAdded() && getView() != null) { + getView().findViewById(R.id.editor_progress).setVisibility(shown ? View.VISIBLE : View.GONE); + } + } + public void resetUploadingMediaToFailed(Set failedMediaIds) { // get all media failed for this post, and represent it on tje UI if (failedMediaIds != null && !failedMediaIds.isEmpty()) { @@ -413,6 +428,7 @@ public void onAttach(Activity activity) { @Override public void onSaveInstanceState(Bundle outState) { outState.putBoolean(KEY_HTML_MODE_ENABLED, mHtmlModeEnabled); + outState.putBoolean(KEY_EDITOR_DID_MOUNT, mEditorDidMount); } @Override From b77a6e5c358ddb1f9eb74b28e8cb0fdc19c0fbf5 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Mar 2019 14:59:22 +0200 Subject: [PATCH 23/25] Update Aztec hash --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index bfe4de3f174c..bfda391ff725 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = 'bd1c9fa37ff5f332720186c3f5d1dee5f4e0944d' + aztecVersion = 'ee83fa8f21b2f60d0b3ca147ecb9e4747898e60a' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index a411c3bc02f1..5a84c57950c6 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit a411c3bc02f189ec07e260143bb8cfed9c60ce72 +Subproject commit 5a84c57950c6d8de5550a509f468d65beb3e83e6 From 110b210b46293056cc41a4445a9b4a2a6bef63a2 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Mar 2019 16:21:10 +0200 Subject: [PATCH 24/25] Point to the release Aztec tag --- libs/editor/WordPressEditor/build.gradle | 2 +- libs/gutenberg-mobile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/editor/WordPressEditor/build.gradle b/libs/editor/WordPressEditor/build.gradle index bfda391ff725..e72f7c25e874 100644 --- a/libs/editor/WordPressEditor/build.gradle +++ b/libs/editor/WordPressEditor/build.gradle @@ -1,7 +1,7 @@ buildscript { ext { - aztecVersion = 'ee83fa8f21b2f60d0b3ca147ecb9e4747898e60a' + aztecVersion = 'v1.3.21' } repositories { diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 5a84c57950c6..39b052a5b904 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 5a84c57950c6d8de5550a509f468d65beb3e83e6 +Subproject commit 39b052a5b90497c3169513e0fb3ff5ae963ca5ef From 1ed5ebaab3a1096c87b9a9255c05faa51280b74d Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Mar 2019 16:47:19 +0200 Subject: [PATCH 25/25] Point to the merged gb-mobile commit --- libs/gutenberg-mobile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/gutenberg-mobile b/libs/gutenberg-mobile index 39b052a5b904..90cce4eb0171 160000 --- a/libs/gutenberg-mobile +++ b/libs/gutenberg-mobile @@ -1 +1 @@ -Subproject commit 39b052a5b90497c3169513e0fb3ff5ae963ca5ef +Subproject commit 90cce4eb0171c776b74a7989ffd04e769cc10bef