wordpress-mobile / AztecEditor-Android

A reusable native Android rich text editor component.
Mozilla Public License 2.0
675 stars 112 forks source link

HTML mode #62

Closed 0nko closed 7 years ago

0nko commented 7 years ago

Addresses #14 and #43.

Jsoup library is used for HTML formatting, because it's easy and fast to use. This can be later replaced with some custom code manipulation, like in the current hybrid editor. However, there are a lot of formatting hacks there that were necessary because of WebKit (for example, all <p> had to be replaced with <div>).

The Format class contains the ported javascript code from the current editor, but it's commented out for now.

I've also added the Merriweather font to visual mode in this PR because it's just a couple of lines of code with TypefaceCache and I didn't want to add the same code in a different PR.

theck13 commented 7 years ago

We can utilize Kotlin's null safety to remove null checks throughout the code. For example, we can replace this...

fun setCustomTypeface(context: Context?, view: TextView?, typefaceName: String?) {
    if (context == null || view == null || typefaceName == null) {
        return
    }

    // skip at design-time
    if (view.isInEditMode) return

    val typeface = getTypeface(context, typefaceName)
    if (typeface != null) {
        view.typeface = typeface
    }
}

with this...

fun setCustomTypeface(context: Context?, view: TextView?, typefaceName: String?) {
    // skip at design-time
    if (view?.isInEditMode == true) return

    val typeface = getTypeface(context, typefaceName)
    if (typeface != null) {
        view?.typeface = typeface
    }
}

if we want to minimize the code.

theck13 commented 7 years ago

Should the history (i.e. undo and redo) work for the HTML view as well?

theck13 commented 7 years ago

Buttons stay selected when switched to the HTML view. The examples below are for the link button, but I confirmed the behavior for all buttons.

link

html

theck13 commented 7 years ago

If you press the Undo action right after switching to the source view, everything is deleted. It can be reverted by tapping the Redo action, but it will unrecoverable if you go to the visual view before hitting Redo.

0nko commented 7 years ago

Sorry, I should have commented here. I thought I'd finish before you come online today :). I'm still working on the history so that the visual & HTML mode share the same history data.

0nko commented 7 years ago

OK, @theck13, give it a go. I think it's working well enough but when you switch from HTML mode to visual mode with invalid HTML then the parser tries to fix things and you can get weird result when you switch back to HTML. I'm not sure what to do with that so let's just leave it for later...

Sorry for the size, it grew pretty big.

theck13 commented 7 years ago

It looks like there is a merge conflict. Would you like to resolve that before or after the review?

0nko commented 7 years ago

I've resolved the conflicts. It's ready.

theck13 commented 7 years ago

I'm getting a crash when editing the HTML. The stack trace is below.

09-02 09:32:27.006 20413-20413/org.wordpress.aztec E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.wordpress.aztec, PID: 20413
    Theme: themes:{}
    java.lang.IndexOutOfBoundsException
        at java.util.LinkedList.remove(LinkedList.java:660)
        at org.wordpress.aztec.History.handleHistory(History.kt:44)
        at org.wordpress.aztec.source.SourceViewEditText.afterTextChanged(SourceViewEditText.kt:81)
        at android.widget.TextView.sendAfterTextChanged(TextView.java:8004)
        at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10165)
        at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1043)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:560)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:225)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:224)
        at android.view.inputmethod.BaseInputConnection.deleteSurroundingText(BaseInputConnection.java:244)
        at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:389)
        at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5461)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Reproduced

  1. Tap HTML button.
  2. Select end of first line.
  3. Tap Backspace key until crash.

Tested

LG G4 (LG-H815) on Android 6.0.1 with AztecDemo 1.0

0nko commented 7 years ago

Thanks Tyler. That should fix it.

theck13 commented 7 years ago

:shipit: