opt: communication between editor and javascript
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package com.stardust.scriptdroid.ui.edit;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
@@ -11,7 +10,6 @@ import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ActionMode;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
@@ -27,28 +25,22 @@ import android.webkit.WebViewClient;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
|
||||
import org.jdeferred.Deferred;
|
||||
import org.jdeferred.DoneCallback;
|
||||
import org.jdeferred.impl.DeferredObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
|
||||
@@ -76,11 +68,6 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
private Callback mCallback;
|
||||
private Deferred<Void, Void, Void> mPageFinished = new DeferredObject<>();
|
||||
|
||||
private PublishSubject<String> mStringFromJs;
|
||||
private PublishSubject<Integer> mIntFromJs;
|
||||
private String mTextFromAndroid;
|
||||
|
||||
|
||||
public CodeMirrorEditor(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
@@ -212,41 +199,25 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
}
|
||||
|
||||
public void setText(final String text) {
|
||||
mTextFromAndroid = text;
|
||||
mPageFinished.promise().done(result -> evalJavaScript("editor.setValue(__bridge__.getStringFromAndroid());"));
|
||||
int id = SharedVariables.put(text);
|
||||
mPageFinished.promise().done(result -> evalJavaScript(String.format(Locale.getDefault(),
|
||||
"editor.setValue(__bridge__.getStringFromAndroid(%d));", id)));
|
||||
}
|
||||
|
||||
|
||||
public void insert(String text) {
|
||||
mTextFromAndroid = text;
|
||||
mPageFinished.promise().done(result -> evalJavaScript("editor.replaceSelection(__bridge__.getStringFromAndroid());"));
|
||||
int id = SharedVariables.put(text);
|
||||
mPageFinished.promise().done(result -> evalJavaScript(String.format(Locale.getDefault(),
|
||||
"editor.replaceSelection(__bridge__.getStringFromAndroid(%d));", id)));
|
||||
}
|
||||
|
||||
|
||||
public void loadFile(final File file) {
|
||||
setProgress(true);
|
||||
Observable.fromCallable(() -> PFiles.read(file))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(s -> {
|
||||
setText(s);
|
||||
setProgress(false);
|
||||
}, err -> {
|
||||
err.printStackTrace();
|
||||
Toast.makeText(getContext(), getContext().getString(R.string.text_cannot_read_file, file.getPath()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
||||
public Observable<String> getText() {
|
||||
mStringFromJs = PublishSubject.create();
|
||||
evalJavaScript("__bridge__.setStringFromJs(editor.getValue());");
|
||||
return mStringFromJs;
|
||||
return evalString("editor.getValue()");
|
||||
}
|
||||
|
||||
public Observable<String> getLine() {
|
||||
mStringFromJs = PublishSubject.create();
|
||||
evalJavaScript("__bridge__.setStringFromJs(editor.getLine(editor.getCursor().line))");
|
||||
return mStringFromJs;
|
||||
return evalString("editor.getLine(editor.getCursor().line)");
|
||||
}
|
||||
|
||||
public void deleteLine() {
|
||||
@@ -297,9 +268,10 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
}
|
||||
|
||||
public Observable<Integer> getLineCount() {
|
||||
mIntFromJs = PublishSubject.create();
|
||||
evalJavaScript("__bridge__.setIntFromJs(editor.lineCount())");
|
||||
return mIntFromJs;
|
||||
PublishSubject<Integer> publishSubject = PublishSubject.create();
|
||||
int id = SharedVariables.put(publishSubject);
|
||||
evalJavaScript(String.format(Locale.getDefault(), "__bridge__.setIntFromJs(%d, editor.lineCount())", id));
|
||||
return publishSubject;
|
||||
}
|
||||
|
||||
|
||||
@@ -387,9 +359,14 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
}
|
||||
|
||||
public Observable<String> getSelection() {
|
||||
mStringFromJs = PublishSubject.create();
|
||||
evalJavaScript("__bridge__.setStringFromJs(editor.getSelection());");
|
||||
return mStringFromJs;
|
||||
return evalString("editor.getSelection()");
|
||||
}
|
||||
|
||||
private Observable<String> evalString(String expr) {
|
||||
PublishSubject<String> publishSubject = PublishSubject.create();
|
||||
int id = SharedVariables.put(publishSubject);
|
||||
evalJavaScript(String.format(Locale.getDefault(), "__bridge__.setStringFromJs(%d, %s);", id, expr));
|
||||
return publishSubject;
|
||||
}
|
||||
|
||||
public void replaceSelection() {
|
||||
@@ -412,30 +389,26 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
public class JavaScriptBridge {
|
||||
|
||||
@JavascriptInterface
|
||||
public void setStringFromJs(String text) {
|
||||
if (mStringFromJs == null) {
|
||||
public void setStringFromJs(int id, String text) {
|
||||
PublishSubject<String> publishSubject = SharedVariables.remove(id);
|
||||
if (publishSubject == null)
|
||||
return;
|
||||
}
|
||||
mStringFromJs.onNext(text);
|
||||
mStringFromJs.onComplete();
|
||||
mStringFromJs = null;
|
||||
publishSubject.onNext(text);
|
||||
publishSubject.onComplete();
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void setIntFromJs(int i) {
|
||||
if (mIntFromJs == null) {
|
||||
public void setIntFromJs(int id, int i) {
|
||||
PublishSubject<Integer> publishSubject = SharedVariables.remove(id);
|
||||
if (publishSubject == null)
|
||||
return;
|
||||
}
|
||||
mIntFromJs.onNext(i);
|
||||
mIntFromJs.onComplete();
|
||||
mIntFromJs = null;
|
||||
publishSubject.onNext(i);
|
||||
publishSubject.onComplete();
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public String getStringFromAndroid() {
|
||||
String t = mTextFromAndroid;
|
||||
mTextFromAndroid = null;
|
||||
return t;
|
||||
public String getStringFromAndroid(int id) {
|
||||
return SharedVariables.remove(id);
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
@@ -104,6 +105,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
private boolean mReadOnly = false;
|
||||
private ScriptExecution mScriptExecution;
|
||||
private boolean mTextChanged = false;
|
||||
private boolean mInitialText = false;
|
||||
private AutoCompletion mAutoCompletion;
|
||||
private FunctionsKeyboardHelper mFunctionsKeyboardHelper;
|
||||
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
||||
@@ -180,17 +182,39 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
String path = intent.getStringExtra(EXTRA_PATH);
|
||||
String content = intent.getStringExtra(EXTRA_CONTENT);
|
||||
if (content != null) {
|
||||
mEditor.setText(content);
|
||||
setInitialText(content);
|
||||
} else {
|
||||
mFile = new File(path);
|
||||
if (mName == null) {
|
||||
mName = mFile.getName();
|
||||
}
|
||||
mEditor.loadFile(mFile);
|
||||
loadFile(mFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void loadFile(final File file) {
|
||||
mEditor.setProgress(true);
|
||||
Observable.fromCallable(() -> PFiles.read(file))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(s -> {
|
||||
setInitialText(s);
|
||||
mEditor.setProgress(false);
|
||||
}, err -> {
|
||||
err.printStackTrace();
|
||||
Toast.makeText(getContext(), getContext().getString(R.string.text_cannot_read_file, file.getPath()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
||||
private void setInitialText(String text) {
|
||||
mInitialText = true;
|
||||
mTextChanged = false;
|
||||
mEditor.setText(text);
|
||||
}
|
||||
|
||||
|
||||
private void setMenuItemStatus(int id, boolean enabled) {
|
||||
findViewById(id).setEnabled(enabled);
|
||||
}
|
||||
@@ -230,9 +254,13 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
setTheme(PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
.getString(KEY_EDITOR_THEME, mEditor.getTheme()));
|
||||
mEditor.setCallback((line, cursor) -> {
|
||||
mTextChanged = true;
|
||||
setMenuItemStatus(R.id.save, true);
|
||||
autoComplete(line, cursor);
|
||||
if (mInitialText) {
|
||||
mInitialText = false;
|
||||
} else {
|
||||
mTextChanged = true;
|
||||
setMenuItemStatus(R.id.save, true);
|
||||
autoComplete(line, cursor);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.stardust.scriptdroid.ui.edit;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2018/2/4.
|
||||
*/
|
||||
|
||||
public class SharedVariables {
|
||||
|
||||
private static SparseArray<Object> sSharedVariables = new SparseArray<>();
|
||||
private static AtomicInteger sMaxId = new AtomicInteger();
|
||||
|
||||
|
||||
public static int put(Object value) {
|
||||
int id = sMaxId.getAndIncrement();
|
||||
sSharedVariables.put(id, value);
|
||||
return id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T remove(int id) {
|
||||
Object o = sSharedVariables.get(id);
|
||||
if (o != null)
|
||||
sSharedVariables.remove(id);
|
||||
return (T) o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,11 +41,6 @@ public class FloatyWindowManger {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void closeWindow(FloatyWindow window) {
|
||||
window.close();
|
||||
}
|
||||
|
||||
public static boolean isCircularMenuShowing() {
|
||||
return sCircularMenu != null && sCircularMenu.get() != null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user