From 2449422ad96b1869a489db538bcc89c0afb19148 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Jun 2018 17:43:22 +0300 Subject: [PATCH 01/11] Calculate content change in html editor too --- .../org/wordpress/aztec/demo/MainActivity.kt | 2 +- .../kotlin/org/wordpress/aztec/AztecText.kt | 72 ++++++++++--------- .../aztec/source/SourceViewEditText.kt | 16 ++++- .../wordpress/aztec/toolbar/AztecToolbar.kt | 4 +- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt index 39ff052c5..bb1e6a903 100644 --- a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt +++ b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt @@ -412,7 +412,7 @@ open class MainActivity : AppCompatActivity(), aztec.visualEditor.setCalypsoMode(false) aztec.sourceEditor?.setCalypsoMode(false) - aztec.sourceEditor?.displayStyledAndFormattedHtml(EXAMPLE) + aztec.sourceEditor?.displayStyledAndFormattedHtml(EXAMPLE, false) aztec.addPlugin(CssUnderlinePlugin()) } diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index de1ffc7db..f0b667a2c 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -160,6 +160,40 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown bitmap.density = DisplayMetrics.DENSITY_DEFAULT return BitmapDrawable(context.resources, bitmap) } + + @Throws(NoSuchAlgorithmException::class) + private fun calculateSHA256(s: String): ByteArray { + val digest = MessageDigest.getInstance("SHA-256") + digest.update(s.toByteArray()) + return digest.digest() + } + + fun calculateInitialHTMLSHA(initialHTMLParsed: String, initialEditorContentParsedSHA256: ByteArray): ByteArray { + try { + // Do not recalculate the hash if it's not the first call to `fromHTML`. + if (initialEditorContentParsedSHA256.isEmpty() || Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(""))) { + return calculateSHA256(initialHTMLParsed) + } + } catch (e: Throwable) { + // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException + } + + return ByteArray(0) + } + + fun hasChanges(initialEditorContentParsedSHA256: ByteArray, newContent: String): EditorHasChanges { + if (!initialEditorContentParsedSHA256.isEmpty()) { + try { + if (Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(newContent))) { + return EditorHasChanges.NO_CHANGES + } + return EditorHasChanges.CHANGES + } catch (e: Throwable) { + // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException + } + } + return EditorHasChanges.UNKNOWN + } } enum class EditorHasChanges { @@ -175,7 +209,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown private var consumeSelectionChangedEvent: Boolean = false private var isInlineTextHandlerEnabled: Boolean = true private var bypassObservationQueue: Boolean = false - private var initialEditorContentParsedSHA256: ByteArray = ByteArray(0) + + var initialEditorContentParsedSHA256: ByteArray = ByteArray(0) private var onSelectionChangedListener: OnSelectionChangedListener? = null private var onImeBackListener: OnImeBackListener? = null @@ -993,7 +1028,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown setSelection(cursorPosition) - calculateInitialHTMLSHA() + initialEditorContentParsedSHA256 = calculateInitialHTMLSHA(toPlainHtml(false), initialEditorContentParsedSHA256) loadImages() loadVideos() @@ -1069,37 +1104,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown } } - private fun calculateInitialHTMLSHA() { - try { - // Do not recalculate the hash if it's not the first call to `fromHTML`. - if (initialEditorContentParsedSHA256.isEmpty() || Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(""))) { - val initialHTMLParsed = toPlainHtml(false) - initialEditorContentParsedSHA256 = calculateSHA256(initialHTMLParsed) - } - } catch (e: Throwable) { - // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException - } - } - - @Throws(NoSuchAlgorithmException::class) - private fun calculateSHA256(s: String): ByteArray { - val digest = MessageDigest.getInstance("SHA-256") - digest.update(s.toByteArray()) - return digest.digest() - } - open fun hasChanges(): EditorHasChanges { - if (!initialEditorContentParsedSHA256.isEmpty()) { - try { - if (Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(toPlainHtml(false)))) { - return EditorHasChanges.NO_CHANGES - } - return EditorHasChanges.CHANGES - } catch (e: Throwable) { - // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException - } - } - return EditorHasChanges.UNKNOWN + return hasChanges(initialEditorContentParsedSHA256, toPlainHtml(false)) } // returns regular or "calypso" html depending on the mode @@ -1473,7 +1479,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown editHtml = unknownHtmlSpan.rawHtml.toString() } - source.displayStyledAndFormattedHtml(editHtml) + source.displayStyledAndFormattedHtml(editHtml, hasChanges() != EditorHasChanges.NO_CHANGES) builder.setView(dialogView) builder.setPositiveButton(R.string.block_editor_dialog_button_save, { _, _ -> diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt index c62d225a6..a0afdddbf 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt @@ -15,6 +15,7 @@ import android.view.KeyEvent import android.view.MotionEvent import android.view.View import org.wordpress.aztec.AztecText +import org.wordpress.aztec.AztecText.EditorHasChanges import org.wordpress.aztec.AztecTextAccessibilityDelegate import org.wordpress.aztec.History import org.wordpress.aztec.R @@ -44,6 +45,8 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex private var accessibilityDelegate = AztecTextAccessibilityDelegate(this) + private var initialEditorContentParsedSHA256: ByteArray = ByteArray(0) + constructor(context: Context) : super(context) { init(null) } @@ -94,6 +97,7 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex visibility = customState.getInt("visibility") val retainedContent = InstanceStateUtils.readAndPurgeTempInstance(RETAINED_CONTENT_KEY, "", savedState.state) setText(retainedContent) + initialEditorContentParsedSHA256 = customState.getByteArray(AztecText.RETAINED_INITIAL_HTML_PARSED_SHA256_KEY) } // Do not include the content of the editor when saving state to bundle. @@ -106,6 +110,8 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex override fun onSaveInstanceState(): Parcelable { val bundle = Bundle() + bundle.putByteArray(org.wordpress.aztec.AztecText.RETAINED_INITIAL_HTML_PARSED_SHA256_KEY, + initialEditorContentParsedSHA256) InstanceStateUtils.writeTempInstance(context, null, RETAINED_CONTENT_KEY, text.toString(), bundle) val superState = super.onSaveInstanceState() val savedState = SavedState(superState) @@ -183,12 +189,16 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex } } - fun displayStyledAndFormattedHtml(source: String) { + fun displayStyledAndFormattedHtml(source: String, hasChangesAlready: Boolean) { val styledHtml = styleHtml(Format.addSourceEditorFormatting(source, isInCalypsoMode)) disableTextChangedListener() val cursorPosition = consumeCursorTag(styledHtml) text = styledHtml + if (!hasChangesAlready) { + initialEditorContentParsedSHA256 = AztecText.calculateInitialHTMLSHA(getPureHtml(false), + initialEditorContentParsedSHA256) + } enableTextChangedListener() if (cursorPosition > 0) @@ -248,6 +258,10 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex return isThereClosingBracketBeforeOpeningBracket && isThereOpeningBracketBeforeClosingBracket } + fun hasChanges(): EditorHasChanges { + return AztecText.hasChanges(initialEditorContentParsedSHA256, getPureHtml(false)) + } + fun getPureHtml(withCursorTag: Boolean = false): String { if (withCursorTag) { disableTextChangedListener() diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt b/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt index cc3c703b4..ef3b27d81 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt @@ -25,6 +25,7 @@ import android.widget.Toast import android.widget.ToggleButton import org.wordpress.android.util.AppLog import org.wordpress.aztec.AztecText +import org.wordpress.aztec.AztecText.EditorHasChanges.NO_CHANGES import org.wordpress.aztec.AztecTextFormat import org.wordpress.aztec.ITextFormat import org.wordpress.aztec.R @@ -565,7 +566,8 @@ class AztecToolbar : FrameLayout, IAztecToolbar, OnMenuItemClickListener { if (sourceEditor == null) return if (editor!!.visibility == View.VISIBLE) { - sourceEditor!!.displayStyledAndFormattedHtml(editor!!.toPlainHtml(true)) + sourceEditor!!.displayStyledAndFormattedHtml(editor!!.toPlainHtml(true), + editor!!.hasChanges() != NO_CHANGES) editor!!.visibility = View.GONE sourceEditor!!.visibility = View.VISIBLE From 9b8bccc1de64554613a50f4bdeea9216a6575b05 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Wed, 6 Jun 2018 18:47:16 +0300 Subject: [PATCH 02/11] Return the calculated value if not recalculating --- aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index f0b667a2c..a1532cb99 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -173,6 +173,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown // Do not recalculate the hash if it's not the first call to `fromHTML`. if (initialEditorContentParsedSHA256.isEmpty() || Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(""))) { return calculateSHA256(initialHTMLParsed) + } else { + return initialEditorContentParsedSHA256; } } catch (e: Throwable) { // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException From 18c5f848d5b28666f99d77873794ad4644b7c796 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 02:21:03 +0300 Subject: [PATCH 03/11] Remove redudant semicolon to fix ktlint --- aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index a1532cb99..795c76e2c 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -174,7 +174,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown if (initialEditorContentParsedSHA256.isEmpty() || Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(""))) { return calculateSHA256(initialHTMLParsed) } else { - return initialEditorContentParsedSHA256; + return initialEditorContentParsedSHA256 } } catch (e: Throwable) { // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException From 16902ea25464a589e9a2b197989962da974e2d98 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 15:07:49 +0300 Subject: [PATCH 04/11] Don't mutate text to insert the cursor tag --- .../wordpress/aztec/source/SourceViewEditText.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt index a0afdddbf..02a198818 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt @@ -263,17 +263,22 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex } fun getPureHtml(withCursorTag: Boolean = false): String { + val str: String + if (withCursorTag) { - disableTextChangedListener() + val withCursor = StringBuffer(text) if (!isCursorInsideTag()) { - text.insert(selectionEnd, "") + withCursor.insert(selectionEnd, "") } else { - text.insert(text.lastIndexOf("<", selectionEnd), "") + withCursor.insert(withCursor.lastIndexOf("<", selectionEnd), "") } - enableTextChangedListener() + + str = withCursor.toString() + } else { + str = text.toString() } - return Format.removeSourceEditorFormatting(text.toString(), isInCalypsoMode) + return Format.removeSourceEditorFormatting(str, isInCalypsoMode) } fun disableTextChangedListener() { From 3784dcd5e6c3ff6051818fae7200b750fab46d60 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 15:15:03 +0300 Subject: [PATCH 05/11] Prime from visual to get the initial html mutations --- .../main/kotlin/org/wordpress/aztec/demo/MainActivity.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt index bb1e6a903..9c7056e45 100644 --- a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt +++ b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt @@ -412,16 +412,19 @@ open class MainActivity : AppCompatActivity(), aztec.visualEditor.setCalypsoMode(false) aztec.sourceEditor?.setCalypsoMode(false) - aztec.sourceEditor?.displayStyledAndFormattedHtml(EXAMPLE, false) - aztec.addPlugin(CssUnderlinePlugin()) } if (savedInstanceState == null) { - aztec.visualEditor.fromHtml(aztec.sourceEditor?.getPureHtml()!!) + aztec.visualEditor.fromHtml(EXAMPLE) aztec.initSourceEditorHistory() } + if (!isRunningTest) { + aztec.sourceEditor?.displayStyledAndFormattedHtml(aztec.visualEditor.toPlainHtml(true), + aztec.visualEditor.hasChanges() != AztecText.EditorHasChanges.NO_CHANGES) + } + invalidateOptionsHandler = Handler() invalidateOptionsRunnable = Runnable { invalidateOptionsMenu() } } From 67730c46644e39997699c72b1b4b20cfb6daf009 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 15:48:20 +0300 Subject: [PATCH 06/11] Revert "Prime from visual to get the initial html mutations" This reverts commit 3784dcd5e6c3ff6051818fae7200b750fab46d60. --- .../main/kotlin/org/wordpress/aztec/demo/MainActivity.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt index 9c7056e45..bb1e6a903 100644 --- a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt +++ b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt @@ -412,19 +412,16 @@ open class MainActivity : AppCompatActivity(), aztec.visualEditor.setCalypsoMode(false) aztec.sourceEditor?.setCalypsoMode(false) + aztec.sourceEditor?.displayStyledAndFormattedHtml(EXAMPLE, false) + aztec.addPlugin(CssUnderlinePlugin()) } if (savedInstanceState == null) { - aztec.visualEditor.fromHtml(EXAMPLE) + aztec.visualEditor.fromHtml(aztec.sourceEditor?.getPureHtml()!!) aztec.initSourceEditorHistory() } - if (!isRunningTest) { - aztec.sourceEditor?.displayStyledAndFormattedHtml(aztec.visualEditor.toPlainHtml(true), - aztec.visualEditor.hasChanges() != AztecText.EditorHasChanges.NO_CHANGES) - } - invalidateOptionsHandler = Handler() invalidateOptionsRunnable = Runnable { invalidateOptionsMenu() } } From 3e1b4cb0eed084e114942be240ede4585f328772 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 15:49:43 +0300 Subject: [PATCH 07/11] On mode switch, set editor's text only if changes detected --- aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt | 2 +- .../org/wordpress/aztec/source/SourceViewEditText.kt | 8 +++----- .../kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt | 9 ++++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index 795c76e2c..33474e004 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -1481,7 +1481,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown editHtml = unknownHtmlSpan.rawHtml.toString() } - source.displayStyledAndFormattedHtml(editHtml, hasChanges() != EditorHasChanges.NO_CHANGES) + source.displayStyledAndFormattedHtml(editHtml) builder.setView(dialogView) builder.setPositiveButton(R.string.block_editor_dialog_button_save, { _, _ -> diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt index 02a198818..fbc6b8f1e 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/source/SourceViewEditText.kt @@ -189,16 +189,14 @@ open class SourceViewEditText : android.support.v7.widget.AppCompatEditText, Tex } } - fun displayStyledAndFormattedHtml(source: String, hasChangesAlready: Boolean) { + fun displayStyledAndFormattedHtml(source: String) { val styledHtml = styleHtml(Format.addSourceEditorFormatting(source, isInCalypsoMode)) disableTextChangedListener() val cursorPosition = consumeCursorTag(styledHtml) text = styledHtml - if (!hasChangesAlready) { - initialEditorContentParsedSHA256 = AztecText.calculateInitialHTMLSHA(getPureHtml(false), - initialEditorContentParsedSHA256) - } + initialEditorContentParsedSHA256 = AztecText.calculateInitialHTMLSHA(getPureHtml(false), + initialEditorContentParsedSHA256) enableTextChangedListener() if (cursorPosition > 0) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt b/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt index ef3b27d81..60ab0a8c5 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/toolbar/AztecToolbar.kt @@ -566,14 +566,17 @@ class AztecToolbar : FrameLayout, IAztecToolbar, OnMenuItemClickListener { if (sourceEditor == null) return if (editor!!.visibility == View.VISIBLE) { - sourceEditor!!.displayStyledAndFormattedHtml(editor!!.toPlainHtml(true), - editor!!.hasChanges() != NO_CHANGES) + if (editor!!.hasChanges() != NO_CHANGES) { + sourceEditor!!.displayStyledAndFormattedHtml(editor!!.toPlainHtml(true)) + } editor!!.visibility = View.GONE sourceEditor!!.visibility = View.VISIBLE toggleHtmlMode(true) } else { - editor!!.fromHtml(sourceEditor!!.getPureHtml(true)) + if (sourceEditor!!.hasChanges() != NO_CHANGES) { + editor!!.fromHtml(sourceEditor!!.getPureHtml(true)) + } editor!!.visibility = View.VISIBLE sourceEditor!!.visibility = View.GONE From fbb9fc9302b0864d0a63957de3272ef25884bfd4 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 15:55:47 +0300 Subject: [PATCH 08/11] displayStyledAndFormattedHtml only takes one param now --- app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt index bb1e6a903..39ff052c5 100644 --- a/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt +++ b/app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt @@ -412,7 +412,7 @@ open class MainActivity : AppCompatActivity(), aztec.visualEditor.setCalypsoMode(false) aztec.sourceEditor?.setCalypsoMode(false) - aztec.sourceEditor?.displayStyledAndFormattedHtml(EXAMPLE, false) + aztec.sourceEditor?.displayStyledAndFormattedHtml(EXAMPLE) aztec.addPlugin(CssUnderlinePlugin()) } From 2c909e7bc9194901343ffa8462ce9e763dd18e0e Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 17:05:30 +0300 Subject: [PATCH 09/11] Report UKNONWN only on error --- .../main/kotlin/org/wordpress/aztec/AztecText.kt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index 33474e004..c90f2b711 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -184,17 +184,15 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown } fun hasChanges(initialEditorContentParsedSHA256: ByteArray, newContent: String): EditorHasChanges { - if (!initialEditorContentParsedSHA256.isEmpty()) { - try { - if (Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(newContent))) { - return EditorHasChanges.NO_CHANGES - } - return EditorHasChanges.CHANGES - } catch (e: Throwable) { - // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException + try { + if (Arrays.equals(initialEditorContentParsedSHA256, calculateSHA256(newContent))) { + return EditorHasChanges.NO_CHANGES } + return EditorHasChanges.CHANGES + } catch (e: Throwable) { + // Do nothing here. `toPlainHtml` can throw exceptions, also calculateSHA256 -> NoSuchAlgorithmException + return EditorHasChanges.UNKNOWN } - return EditorHasChanges.UNKNOWN } } From 69b04a346dba6f639a44eeaa6cefcb8ba16e2294 Mon Sep 17 00:00:00 2001 From: Stefanos Togkoulidis Date: Thu, 7 Jun 2018 17:05:51 +0300 Subject: [PATCH 10/11] Shamelessly copied from wpandroid PR #682 --- .../org/wordpress/aztec/demo/Matchers.kt | 21 ++++++++++++ .../wordpress/aztec/demo/pages/EditorPage.kt | 19 +++-------- .../demo/tests/MixedTextFormattingTests.kt | 32 ++++++++++++++++++- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/Matchers.kt b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/Matchers.kt index cd40c5012..b2cff6877 100644 --- a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/Matchers.kt +++ b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/Matchers.kt @@ -5,7 +5,9 @@ import android.widget.EditText import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.TypeSafeMatcher +import org.wordpress.aztec.AztecText import org.wordpress.aztec.source.Format +import org.wordpress.aztec.source.SourceViewEditText object Matchers { fun withRegex(expected: Regex): Matcher { @@ -45,4 +47,23 @@ object Matchers { } } } + + fun hasContentChanges(shouldHaveChanges: AztecText.EditorHasChanges): TypeSafeMatcher { + + return object : TypeSafeMatcher() { + override fun describeTo(description: Description) { + description.appendText("User has made changes to the post: $shouldHaveChanges") + } + + public override fun matchesSafely(view: View): Boolean { + if (view is SourceViewEditText) { + return view.hasChanges() == shouldHaveChanges + } + if (view is AztecText) { + return view.hasChanges() == shouldHaveChanges + } + return false + } + } + } } diff --git a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt index 5392147c4..b5f8405cd 100644 --- a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt +++ b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt @@ -371,21 +371,12 @@ class EditorPage : BasePage() { } fun hasChanges(shouldHaveChanges : AztecText.EditorHasChanges): EditorPage { - val hasNoChangesMatcher = object : TypeSafeMatcher() { - override fun describeTo(description: Description) { - description.appendText("User has made changes to the post: $shouldHaveChanges") - } - - public override fun matchesSafely(view: View): Boolean { - if (view is AztecText) { - return view.hasChanges() == shouldHaveChanges - } - - return false - } - } + editor.check(matches(Matchers.hasContentChanges(shouldHaveChanges))) + return this + } - editor.check(matches(hasNoChangesMatcher)) + fun hasChangesHTML(shouldHaveChanges : AztecText.EditorHasChanges): EditorPage { + htmlEditor.check(matches(Matchers.hasContentChanges(shouldHaveChanges))) return this } diff --git a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/tests/MixedTextFormattingTests.kt b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/tests/MixedTextFormattingTests.kt index e1b77a9e7..d77e52aa3 100644 --- a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/tests/MixedTextFormattingTests.kt +++ b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/tests/MixedTextFormattingTests.kt @@ -254,7 +254,6 @@ class MixedTextFormattingTests : BaseTest() { .hasChanges(AztecText.EditorHasChanges.NO_CHANGES) // Verify that the user had not changed the input } - @Ignore("Until this issue is fixed: https://github.com/wordpress-mobile/AztecEditor-Android/issues/698") @Test fun testHasChangesWithMixedBoldAndItalicFormatting() { val input = "bold italic bold" @@ -271,4 +270,35 @@ class MixedTextFormattingTests : BaseTest() { .hasChanges(AztecText.EditorHasChanges.CHANGES) .verifyHTML(afterParser) } + + @Test + fun testHasChangesOnHTMLEditor() { + val input = "Test" + val insertedText = " text added" + val afterParser = "Test$insertedText" + + EditorPage().toggleHtml() + .insertHTML(input) + .toggleHtml() + .toggleHtml() // switch back to HTML editor + .insertHTML(insertedText) + .hasChangesHTML(AztecText.EditorHasChanges.CHANGES) + .verifyHTML(afterParser) + } + + @Test + fun testHasChangesOnHTMLEditorTestedFromVisualEditor() { + val input = "Test" + val insertedText = " text added" + val afterParser = "Test$insertedText" + + EditorPage().toggleHtml() + .insertHTML(input) + .toggleHtml() + .toggleHtml() // switch back to HTML editor + .insertHTML(insertedText) + .hasChangesHTML(AztecText.EditorHasChanges.CHANGES) + .toggleHtml() // switch back to Visual editor + .verify(afterParser) + } } From efd43ed795f4c321590f1f7ff720eb1c4d4390a7 Mon Sep 17 00:00:00 2001 From: Danilo Ercoli Date: Thu, 7 Jun 2018 17:46:12 +0200 Subject: [PATCH 11/11] Remove unused imports --- .../kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt index b5f8405cd..dfc3b9c95 100644 --- a/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt +++ b/app/src/androidTest/kotlin/org/wordpress/aztec/demo/pages/EditorPage.kt @@ -14,11 +14,9 @@ import android.support.test.espresso.matcher.ViewMatchers.withId import android.support.test.espresso.matcher.ViewMatchers.withText import android.view.KeyEvent import android.view.View -import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.hasToString -import org.hamcrest.TypeSafeMatcher import org.wordpress.aztec.AztecText import org.wordpress.aztec.demo.Actions import org.wordpress.aztec.demo.BasePage