mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-21 21:01:43 +08:00
Merge branch 'dev' of https://github.com/hyb1996/NoRootScriptDroid into dev
This commit is contained in:
commit
5329278e8d
Binary file not shown.
@ -8,8 +8,8 @@ android {
|
||||
applicationId "org.autojs.autojs"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 406
|
||||
versionName "4.0.2 Alpha2"
|
||||
versionCode 408
|
||||
versionName "4.0.2 Alpha3"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
|
||||
@ -73,6 +73,7 @@
|
||||
|
||||
<activity
|
||||
android:name=".ui.edit.EditActivity_"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:multiprocess="true"
|
||||
android:theme="@style/EditorTheme">
|
||||
</activity>
|
||||
@ -81,7 +82,10 @@
|
||||
android:name=".ui.settings.SettingsActivity_"
|
||||
android:theme="@style/AppTheme.Settings"/>
|
||||
<activity android:name=".ui.error.ErrorReportActivity"/>
|
||||
<activity android:name=".external.tasker.TaskerScriptEditActivity_"/>
|
||||
<activity
|
||||
android:name=".external.tasker.TaskerScriptEditActivity_"
|
||||
android:configChanges="orientation|screenSize"
|
||||
/>
|
||||
<activity android:name=".ui.edit.ViewSampleActivity"/>
|
||||
<activity
|
||||
android:name=".ui.user.LoginActivity_"
|
||||
|
||||
@ -5,9 +5,11 @@
|
||||
"editor.background": "#1E1E1E",
|
||||
"editor.foreground": "#D4D4D4",
|
||||
"editorLineNumber.foreground": "#404040",
|
||||
"editorBreakpoint.foreground": "#1976D2",
|
||||
"imeBar.background": "#dd1e1e1e",
|
||||
"imeBar.foreground": "#f1f1f1",
|
||||
"editor.lineHighlightBackground": "#2e2e35"
|
||||
"editor.lineHighlightBackground": "#2e2e35",
|
||||
"editor.debuggingLineBackground": "#40c4ff"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
|
||||
@ -499,6 +499,8 @@
|
||||
"editor.background": "#F5F5F5",
|
||||
"editor.foreground": "#000000",
|
||||
"editor.lineHighlightBackground": "#E4F6D4",
|
||||
"editor.debuggingLineBackground": "#40c4ff",
|
||||
"editorBreakpoint.foreground": "#03A9F4",
|
||||
"focusBorder": "#A6B39B",
|
||||
"pickerGroup.foreground": "#A6B39B",
|
||||
"pickerGroup.border": "#749351",
|
||||
|
||||
@ -22,6 +22,10 @@ public class EditorColors {
|
||||
private String mImeForegroundColor;
|
||||
@SerializedName("editor.lineHighlightBackground")
|
||||
private String mLineHighlightBackground;
|
||||
@SerializedName("editorBreakpoint.foreground")
|
||||
private String mBreakpointForeground;
|
||||
@SerializedName("editor.debuggingLineBackground")
|
||||
private String mDebuggingLineBackground;
|
||||
|
||||
public String getLineHighlightBackground() {
|
||||
return mLineHighlightBackground;
|
||||
@ -86,4 +90,20 @@ public class EditorColors {
|
||||
public void setImeForegroundColor(String imeForegroundColor) {
|
||||
mImeForegroundColor = imeForegroundColor;
|
||||
}
|
||||
|
||||
public String getBreakpointForeground() {
|
||||
return mBreakpointForeground;
|
||||
}
|
||||
|
||||
public void setBreakpointForeground(String breakpointForeground) {
|
||||
mBreakpointForeground = breakpointForeground;
|
||||
}
|
||||
|
||||
public String getDebuggingLineBackground() {
|
||||
return mDebuggingLineBackground;
|
||||
}
|
||||
|
||||
public void setDebuggingLineBackground(String debuggingLineBackground) {
|
||||
mDebuggingLineBackground = debuggingLineBackground;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import com.stardust.app.OnActivityResultDelegate;
|
||||
import com.stardust.autojs.core.permission.OnRequestPermissionsResultCallback;
|
||||
import com.stardust.autojs.core.permission.PermissionRequestProxyActivity;
|
||||
import com.stardust.autojs.core.permission.RequestPermissionCallbacks;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
@ -91,6 +92,13 @@ public class EditActivity extends BaseActivity implements OnActivityResultDelega
|
||||
return mEditorMenu.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
boolean isScriptRunning = mEditorView.getScriptExecutionId() != ScriptExecution.NO_ID;
|
||||
MenuItem forceStopItem = menu.findItem(R.id.action_force_stop);
|
||||
forceStopItem.setEnabled(isScriptRunning);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionModeStarted(ActionMode mode) {
|
||||
|
||||
@ -6,12 +6,14 @@ import android.text.InputType;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.ui.build.BuildActivity;
|
||||
import org.autojs.autojs.ui.build.BuildActivity_;
|
||||
import org.autojs.autojs.ui.edit.editor.CodeEditor;
|
||||
import org.autojs.autojs.ui.log.LogActivity_;
|
||||
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -53,6 +55,21 @@ public class EditorMenu {
|
||||
if (onMoreOptionsSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
if(onDebugOptionsSelected(item)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onDebugOptionsSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_breakpoint:
|
||||
mEditor.addOrRemoveBreakpointAtCurrentLine();
|
||||
return true;
|
||||
case R.id.action_launch_debugger:
|
||||
mEditorView.launchDebugger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,15 +1,23 @@
|
||||
package org.autojs.autojs.ui.edit;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
@ -18,36 +26,43 @@ import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
import com.stardust.util.Callback;
|
||||
import com.stardust.util.ViewUtils;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.EViewGroup;
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.model.autocomplete.AutoCompletion;
|
||||
import org.autojs.autojs.model.autocomplete.CodeCompletion;
|
||||
import org.autojs.autojs.model.autocomplete.CodeCompletions;
|
||||
import org.autojs.autojs.model.autocomplete.Symbols;
|
||||
import org.autojs.autojs.model.indices.Module;
|
||||
import org.autojs.autojs.model.indices.Property;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.ui.doc.ManualDialog;
|
||||
import org.autojs.autojs.model.autocomplete.CodeCompletions;
|
||||
import org.autojs.autojs.ui.edit.completion.CodeCompletionBar;
|
||||
import org.autojs.autojs.model.autocomplete.Symbols;
|
||||
import org.autojs.autojs.ui.edit.editor.CodeEditor;
|
||||
import org.autojs.autojs.ui.edit.keyboard.FunctionsKeyboardHelper;
|
||||
import org.autojs.autojs.ui.edit.keyboard.FunctionsKeyboardView;
|
||||
import org.autojs.autojs.ui.edit.theme.Theme;
|
||||
import org.autojs.autojs.ui.edit.theme.Themes;
|
||||
import org.autojs.autojs.ui.edit.toolbar.DebugToolbarFragment;
|
||||
import org.autojs.autojs.ui.edit.toolbar.DebugToolbarFragment_;
|
||||
import org.autojs.autojs.ui.edit.toolbar.NormalToolbarFragment;
|
||||
import org.autojs.autojs.ui.edit.toolbar.NormalToolbarFragment_;
|
||||
import org.autojs.autojs.ui.edit.toolbar.SearchToolbarFragment;
|
||||
import org.autojs.autojs.ui.edit.toolbar.SearchToolbarFragment_;
|
||||
import org.autojs.autojs.ui.edit.toolbar.ToolbarFragment;
|
||||
import org.autojs.autojs.ui.log.LogActivity_;
|
||||
import org.autojs.autojs.ui.widget.EWebView;
|
||||
import org.autojs.autojs.ui.widget.SimpleTextWatcher;
|
||||
import org.autojs.autojs.ui.widget.ToolbarMenuItem;
|
||||
import com.stardust.util.BackPressedHandler;
|
||||
import com.stardust.util.ViewUtils;
|
||||
import com.stardust.widget.ViewSwitcher;
|
||||
|
||||
import org.androidannotations.annotations.AfterViews;
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EViewGroup;
|
||||
import org.androidannotations.annotations.ViewById;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@ -62,7 +77,7 @@ import static org.autojs.autojs.model.script.Scripts.ACTION_ON_EXECUTION_FINISHE
|
||||
* Created by Stardust on 2017/9/28.
|
||||
*/
|
||||
@EViewGroup(R.layout.editor_view)
|
||||
public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintClickListener, FunctionsKeyboardView.ClickCallback {
|
||||
public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintClickListener, FunctionsKeyboardView.ClickCallback, ToolbarFragment.OnMenuItemClickListener {
|
||||
|
||||
public static final String EXTRA_PATH = "path";
|
||||
public static final String EXTRA_NAME = "name";
|
||||
@ -77,12 +92,6 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
@ViewById(R.id.code_completion_bar)
|
||||
CodeCompletionBar mCodeCompletionBar;
|
||||
|
||||
@ViewById(R.id.toolbar_switcher)
|
||||
ViewSwitcher mToolbarSwitcher;
|
||||
|
||||
@ViewById(R.id.replace)
|
||||
ToolbarMenuItem mReplaceMenuItem;
|
||||
|
||||
@ViewById(R.id.input_method_enhance_bar)
|
||||
View mInputMethodEnhanceBar;
|
||||
|
||||
@ -104,7 +113,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
private String mName;
|
||||
private File mFile;
|
||||
private boolean mReadOnly = false;
|
||||
private ScriptExecution mScriptExecution;
|
||||
private int mScriptExecutionId;
|
||||
private AutoCompletion mAutoCompletion;
|
||||
private Theme mEditorTheme;
|
||||
private FunctionsKeyboardHelper mFunctionsKeyboardHelper;
|
||||
@ -112,7 +121,10 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ACTION_ON_EXECUTION_FINISHED.equals(intent.getAction())) {
|
||||
mScriptExecution = null;
|
||||
mScriptExecutionId = ScriptExecution.NO_ID;
|
||||
if (mDebugging) {
|
||||
exitDebugging();
|
||||
}
|
||||
setMenuItemStatus(R.id.run, true);
|
||||
String msg = intent.getStringExtra(Scripts.EXTRA_EXCEPTION_MESSAGE);
|
||||
int line = intent.getIntExtra(Scripts.EXTRA_EXCEPTION_LINE_NUMBER, -1);
|
||||
@ -126,7 +138,11 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private SparseBooleanArray mMenuItemStatus = new SparseBooleanArray();
|
||||
private String mRestoredText;
|
||||
private NormalToolbarFragment mNormalToolbar = new NormalToolbarFragment_();
|
||||
private boolean mDebugging = false;
|
||||
|
||||
public EditorView(Context context) {
|
||||
super(context);
|
||||
@ -199,6 +215,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void loadFile(final File file) {
|
||||
mEditor.setProgress(true);
|
||||
Observable.fromCallable(() -> PFiles.read(file))
|
||||
@ -225,9 +242,19 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
|
||||
|
||||
private void setMenuItemStatus(int id, boolean enabled) {
|
||||
findViewById(id).setEnabled(enabled);
|
||||
mMenuItemStatus.put(id, enabled);
|
||||
ToolbarFragment fragment = (ToolbarFragment) getActivity().getSupportFragmentManager()
|
||||
.findFragmentById(R.id.toolbar_menu);
|
||||
if (fragment == null) {
|
||||
mNormalToolbar.setMenuItemStatus(id, enabled);
|
||||
} else {
|
||||
fragment.setMenuItemStatus(id, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getMenuItemStatus(int id, boolean defValue) {
|
||||
return mMenuItemStatus.get(id, defValue);
|
||||
}
|
||||
|
||||
@AfterViews
|
||||
void init() {
|
||||
@ -238,9 +265,18 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
setMenuItemStatus(R.id.save, false);
|
||||
mDocsWebView.getWebView().getSettings().setDisplayZoomControls(true);
|
||||
mDocsWebView.getWebView().loadUrl(Pref.getDocumentationUrl() + "index.html");
|
||||
Themes.getCurrent(getContext()).
|
||||
observeOn(AndroidSchedulers.mainThread())
|
||||
Themes.getCurrent(getContext())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::setTheme);
|
||||
initNormalToolbar();
|
||||
}
|
||||
|
||||
private void initNormalToolbar() {
|
||||
mNormalToolbar.setOnMenuItemClickListener(this);
|
||||
Fragment fragment = getActivity().getSupportFragmentManager().findFragmentById(R.id.toolbar_menu);
|
||||
if(fragment == null){
|
||||
showNormalToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpFunctionsKeyboard() {
|
||||
@ -299,8 +335,37 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToolbarMenuItemClick(int id) {
|
||||
switch (id) {
|
||||
case R.id.run:
|
||||
runAndSaveFileIfNeeded();
|
||||
break;
|
||||
case R.id.save:
|
||||
saveFile();
|
||||
break;
|
||||
case R.id.undo:
|
||||
undo();
|
||||
break;
|
||||
case R.id.redo:
|
||||
redo();
|
||||
break;
|
||||
case R.id.replace:
|
||||
replace();
|
||||
break;
|
||||
case R.id.find_next:
|
||||
findNext();
|
||||
break;
|
||||
case R.id.find_prev:
|
||||
findPrev();
|
||||
break;
|
||||
case R.id.cancel_search:
|
||||
cancelSearch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Click(R.id.run)
|
||||
@SuppressLint("CheckResult")
|
||||
public void runAndSaveFileIfNeeded() {
|
||||
save().observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(s -> run());
|
||||
@ -308,17 +373,15 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
|
||||
public void run() {
|
||||
Snackbar.make(this, R.string.text_start_running, Snackbar.LENGTH_SHORT).show();
|
||||
mScriptExecution = Scripts.runWithBroadcastSender(mFile);
|
||||
mScriptExecutionId = Scripts.runWithBroadcastSender(mFile).getId();
|
||||
setMenuItemStatus(R.id.run, false);
|
||||
}
|
||||
|
||||
|
||||
@Click(R.id.undo)
|
||||
public void undo() {
|
||||
mEditor.undo();
|
||||
}
|
||||
|
||||
@Click(R.id.redo)
|
||||
public void redo() {
|
||||
mEditor.redo();
|
||||
}
|
||||
@ -335,32 +398,49 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
|
||||
public void forceStop() {
|
||||
if (mScriptExecution != null) {
|
||||
mScriptExecution.getEngine().forceStop();
|
||||
doWithCurrentEngine(ScriptEngine::forceStop);
|
||||
}
|
||||
|
||||
private void doWithCurrentEngine(Callback<ScriptEngine> callback) {
|
||||
ScriptExecution execution = AutoJs.getInstance().getScriptEngineService().getScriptExecution(mScriptExecutionId);
|
||||
if (execution != null) {
|
||||
ScriptEngine engine = execution.getEngine();
|
||||
if (engine != null) {
|
||||
callback.call(engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Click(R.id.save)
|
||||
public void saveFile() {
|
||||
save().subscribe();
|
||||
}
|
||||
|
||||
@Click(R.id.find_next)
|
||||
void findNext() {
|
||||
mEditor.findNext();
|
||||
}
|
||||
|
||||
@Click(R.id.find_prev)
|
||||
void findPrev() {
|
||||
mEditor.findPrev();
|
||||
}
|
||||
|
||||
@Click(R.id.cancel)
|
||||
void cancelSearch() {
|
||||
mToolbarSwitcher.showFirst();
|
||||
showNormalToolbar();
|
||||
}
|
||||
|
||||
private void showNormalToolbar() {
|
||||
getActivity().getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.toolbar_menu, mNormalToolbar)
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
FragmentActivity getActivity() {
|
||||
Context context = getContext();
|
||||
while (!(context instanceof Activity) && context instanceof ContextWrapper) {
|
||||
context = ((ContextWrapper) context).getBaseContext();
|
||||
}
|
||||
return (FragmentActivity) context;
|
||||
}
|
||||
|
||||
@Click(R.id.replace)
|
||||
void replace() {
|
||||
mEditor.replaceSelection();
|
||||
}
|
||||
@ -374,9 +454,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
|
||||
public void showConsole() {
|
||||
if (mScriptExecution != null) {
|
||||
((JavaScriptEngine) mScriptExecution.getEngine()).getRuntime().console.show();
|
||||
}
|
||||
doWithCurrentEngine(engine -> ((JavaScriptEngine) engine).getRuntime().console.show());
|
||||
}
|
||||
|
||||
public void openByOtherApps() {
|
||||
@ -433,14 +511,22 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
|
||||
public void find(String keywords, boolean usingRegex) {
|
||||
mEditor.find(keywords, usingRegex);
|
||||
mReplaceMenuItem.setVisibility(GONE);
|
||||
mToolbarSwitcher.showSecond();
|
||||
showSearchToolbar(false);
|
||||
}
|
||||
|
||||
private void showSearchToolbar(boolean showReplaceItem) {
|
||||
SearchToolbarFragment searchToolbarFragment = SearchToolbarFragment_.builder()
|
||||
.arg(SearchToolbarFragment.ARGUMENT_SHOW_REPLACE_ITEM, showReplaceItem)
|
||||
.build();
|
||||
searchToolbarFragment.setOnMenuItemClickListener(this);
|
||||
getActivity().getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.toolbar_menu, searchToolbarFragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
public void replace(String keywords, String replacement, boolean usingRegex) {
|
||||
mEditor.replace(keywords, replacement, usingRegex);
|
||||
mReplaceMenuItem.setVisibility(VISIBLE);
|
||||
mToolbarSwitcher.showSecond();
|
||||
showSearchToolbar(true);
|
||||
}
|
||||
|
||||
public void replaceAll(String keywords, String replacement, boolean usingRegex) {
|
||||
@ -448,6 +534,26 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
|
||||
|
||||
public void launchDebugger() {
|
||||
DebugToolbarFragment debugToolbarFragment = DebugToolbarFragment_.builder()
|
||||
.build();
|
||||
getActivity().getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.toolbar_menu, debugToolbarFragment)
|
||||
.commit();
|
||||
mDebugging = true;
|
||||
}
|
||||
|
||||
public void exitDebugging() {
|
||||
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
|
||||
Fragment fragment = fragmentManager.findFragmentById(R.id.toolbar_menu);
|
||||
if (fragment instanceof DebugToolbarFragment) {
|
||||
((DebugToolbarFragment) fragment).detachDebugger();
|
||||
}
|
||||
showNormalToolbar();
|
||||
mEditor.setDebuggingLine(-1);
|
||||
mDebugging = false;
|
||||
}
|
||||
|
||||
private void showErrorMessage(String msg) {
|
||||
Snackbar.make(EditorView.this, getResources().getString(R.string.text_error) + ": " + msg, Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.text_detail, v -> LogActivity_.intent(getContext()).start())
|
||||
@ -511,5 +617,31 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
}
|
||||
}
|
||||
|
||||
public int getScriptExecutionId() {
|
||||
return mScriptExecutionId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ScriptExecution getScriptExecution(){
|
||||
return AutoJs.getInstance().getScriptEngineService().getScriptExecution(mScriptExecutionId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Parcelable onSaveInstanceState() {
|
||||
Bundle bundle = new Bundle();
|
||||
Parcelable superData = super.onSaveInstanceState();
|
||||
bundle.putParcelable("super_data", superData);
|
||||
bundle.putInt("script_execution_id", mScriptExecutionId);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Parcelable state) {
|
||||
Bundle bundle = (Bundle) state;
|
||||
Parcelable superData = bundle.getParcelable("super_data");
|
||||
mScriptExecutionId = bundle.getInt("script_execution_id", ScriptExecution.NO_ID);
|
||||
super.onRestoreInstanceState(superData);
|
||||
setMenuItemStatus(R.id.run, mScriptExecutionId == ScriptExecution.NO_ID);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v7.widget.AppCompatEditText;
|
||||
import android.text.Editable;
|
||||
@ -31,14 +32,19 @@ import android.util.Log;
|
||||
import android.util.TimingLogger;
|
||||
import android.view.Gravity;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.ui.edit.theme.Theme;
|
||||
import org.autojs.autojs.ui.edit.theme.TokenMapping;
|
||||
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
import com.stardust.util.TextUtils;
|
||||
|
||||
import org.mozilla.javascript.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import static org.autojs.autojs.ui.edit.editor.BracketMatching.UNMATCHED_BRACKET;
|
||||
|
||||
/**
|
||||
@ -62,6 +68,8 @@ public class CodeEditText extends AppCompatEditText {
|
||||
private int mFirstLineForDraw = -1, mLastLineForDraw;
|
||||
private int[] mMatchingBrackets = {-1, -1};
|
||||
private int mUnmatchedBracket = -1;
|
||||
private LinkedHashMap<Integer, CodeEditor.Breakpoint> mBreakpoints = new LinkedHashMap<>();
|
||||
private int mDebuggingLine = -1;
|
||||
|
||||
|
||||
public CodeEditText(Context context) {
|
||||
@ -87,6 +95,10 @@ public class CodeEditText extends AppCompatEditText {
|
||||
mLineHighlightPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, CodeEditor.Breakpoint> getBreakpoints() {
|
||||
return mBreakpoints;
|
||||
}
|
||||
|
||||
public void setTheme(Theme theme) {
|
||||
mTheme = theme;
|
||||
invalidate();
|
||||
@ -101,8 +113,8 @@ public class CodeEditText extends AppCompatEditText {
|
||||
updatePaddingForGutter();
|
||||
updateLineRangeForDraw(canvas);
|
||||
|
||||
//绘制当前行高亮需要在绘制光标之前
|
||||
drawLineHighlight(canvas, mLineHighlightPaint, getCurrentLine());
|
||||
//绘制行高亮需要在绘制光标之前
|
||||
drawLineHighlights(canvas);
|
||||
|
||||
//调用super.onDraw绘制光标和选择高亮。因为字体颜色被设置为透明因此super.onDraw()绘制的字体不显示
|
||||
// TODO: 2018/2/24 优化效率。不绘制透明字体。
|
||||
@ -118,6 +130,30 @@ public class CodeEditText extends AppCompatEditText {
|
||||
mLogger.dumpToLog();
|
||||
}
|
||||
|
||||
public int getDebuggingLine() {
|
||||
return mDebuggingLine;
|
||||
}
|
||||
|
||||
public void setDebuggingLine(int debuggingLine) {
|
||||
mDebuggingLine = debuggingLine;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void drawLineHighlights(Canvas canvas) {
|
||||
int currentLine = getCurrentLine();
|
||||
int debugHighlightLine = mDebuggingLine;
|
||||
if (debugHighlightLine != currentLine) {
|
||||
//绘制当前行高亮
|
||||
mLineHighlightPaint.setColor(mTheme.getLineHighlightBackgroundColor());
|
||||
drawLineHighlight(canvas, mLineHighlightPaint, getCurrentLine());
|
||||
}
|
||||
if (debugHighlightLine != -1) {
|
||||
mLineHighlightPaint.setColor(mTheme.getDebuggingLineBackgroundColor());
|
||||
drawLineHighlight(canvas, mLineHighlightPaint, debugHighlightLine);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateLineRangeForDraw(Canvas canvas) {
|
||||
Layout layout = getLayout();
|
||||
if (layout == null)
|
||||
@ -159,15 +195,22 @@ public class CodeEditText extends AppCompatEditText {
|
||||
int scrollX = Math.max(getRealScrollX() - paddingLeft, 0);
|
||||
Paint paint = getPaint();
|
||||
int lineNumberColor = mTheme.getLineNumberColor();
|
||||
int breakPointColor = mTheme.getBreakpointColor();
|
||||
if (DEBUG)
|
||||
Log.d(LOG_TAG, "draw line: " + (mLastLineForDraw - mFirstLineForDraw + 1));
|
||||
mLogger.addSplit("before draw line");
|
||||
for (int line = mFirstLineForDraw; line <= mLastLineForDraw && line < lineCount; line++) {
|
||||
int lineBottom = layout.getLineTop(line + 1);
|
||||
int lineTop = layout.getLineTop(line);
|
||||
int lineBaseline = lineBottom - layout.getLineDescent(line);
|
||||
|
||||
//drawLineNumber
|
||||
String lineNumberText = Integer.toString(line + 1);
|
||||
// if there is a breakpoint at this line, draw highlight background for line number
|
||||
if (mBreakpoints.containsKey(line)) {
|
||||
paint.setColor(breakPointColor);
|
||||
canvas.drawRect(0, lineTop, paddingLeft - 10, lineBottom, paint);
|
||||
}
|
||||
paint.setColor(lineNumberColor);
|
||||
canvas.drawText(lineNumberText, 0, lineNumberText.length(), 10,
|
||||
lineBaseline, paint);
|
||||
@ -225,7 +268,6 @@ public class CodeEditText extends AppCompatEditText {
|
||||
}
|
||||
int lineTop = getLayout().getLineTop(line);
|
||||
int lineBottom = getLayout().getLineTop(line + 1);
|
||||
paint.setColor(mTheme.getLineHighlightBackgroundColor());
|
||||
canvas.drawRect(0, lineTop, canvas.getWidth(), lineBottom, paint);
|
||||
}
|
||||
|
||||
@ -363,4 +405,34 @@ public class CodeEditText extends AppCompatEditText {
|
||||
super.setSelection(index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
Bundle bundle = new Bundle();
|
||||
Parcelable superData = super.onSaveInstanceState();
|
||||
bundle.putParcelable("super_data", superData);
|
||||
bundle.putInt("debugging_line", mDebuggingLine);
|
||||
int[] breakpoints = new int[mBreakpoints.size()];
|
||||
int i = 0;
|
||||
for (CodeEditor.Breakpoint breakpoint : mBreakpoints.values()) {
|
||||
breakpoints[i++] = breakpoint.line;
|
||||
}
|
||||
bundle.putIntArray("breakpoints", breakpoints);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
Bundle bundle = (Bundle) state;
|
||||
Parcelable superData = bundle.getParcelable("super_data");
|
||||
mDebuggingLine = bundle.getInt("debugging_line", -1);
|
||||
int[] breakpoints = bundle.getIntArray("breakpoints");
|
||||
if(breakpoints != null){
|
||||
for (int breakpoint : breakpoints) {
|
||||
mBreakpoints.put(breakpoint, new CodeEditor.Breakpoint(breakpoint));
|
||||
}
|
||||
}
|
||||
super.onRestoreInstanceState(superData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,17 +3,20 @@ package org.autojs.autojs.ui.edit.editor;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.text.Layout;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.android.dx.util.IntList;
|
||||
import com.stardust.autojs.script.JsBeautifier;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.ui.edit.theme.Theme;
|
||||
|
||||
import com.stardust.util.ClipboardUtil;
|
||||
import com.stardust.util.TextUtils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -53,7 +56,6 @@ public class CodeEditor extends HVScrollView {
|
||||
private JsBeautifier mJsBeautifier;
|
||||
private MaterialDialog mProcessDialog;
|
||||
|
||||
|
||||
private CharSequence mReplacement = "";
|
||||
private String mKeywords;
|
||||
private Matcher mMatcher;
|
||||
@ -73,7 +75,7 @@ public class CodeEditor extends HVScrollView {
|
||||
private void init() {
|
||||
//setFillViewport(true);
|
||||
inflate(getContext(), R.layout.code_editor, this);
|
||||
mCodeEditText = (CodeEditText) findViewById(R.id.code_edit_text);
|
||||
mCodeEditText = findViewById(R.id.code_edit_text);
|
||||
mCodeEditText.addTextChangedListener(new AutoIndent(mCodeEditText));
|
||||
mTextViewRedoUndo = new TextViewRedoUndo(mCodeEditText);
|
||||
mJavaScriptHighlighter = new JavaScriptHighlighter(mTheme, mCodeEditText);
|
||||
@ -166,7 +168,8 @@ public class CodeEditor extends HVScrollView {
|
||||
}
|
||||
|
||||
public void jumpTo(int line, int col) {
|
||||
if (line >= mCodeEditText.getLayout().getLineCount() || line < 0) {
|
||||
Layout layout = mCodeEditText.getLayout();
|
||||
if (line < 0 || (layout != null && line >= layout.getLineCount())) {
|
||||
return;
|
||||
}
|
||||
mCodeEditText.setSelection(mCodeEditText.getLayout().getLineStart(line) + col);
|
||||
@ -260,7 +263,7 @@ public class CodeEditor extends HVScrollView {
|
||||
}
|
||||
|
||||
public void findPrev() {
|
||||
if (mMatcher != null){
|
||||
if (mMatcher != null) {
|
||||
Toast.makeText(getContext(), R.string.error_regex_find_prev, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
@ -329,6 +332,31 @@ public class CodeEditor extends HVScrollView {
|
||||
mTextViewRedoUndo.markTextAsUnchanged();
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, Breakpoint> getBreakpoints() {
|
||||
return mCodeEditText.getBreakpoints();
|
||||
}
|
||||
|
||||
public void setDebuggingLine(int line) {
|
||||
jumpTo(line, 0);
|
||||
mCodeEditText.setDebuggingLine(line);
|
||||
}
|
||||
|
||||
public void addOrRemoveBreakpoint(int line) {
|
||||
LinkedHashMap<Integer, Breakpoint> breakpoints = mCodeEditText.getBreakpoints();
|
||||
if (breakpoints.remove(line) == null) {
|
||||
breakpoints.put(line, new Breakpoint(line));
|
||||
}
|
||||
mCodeEditText.invalidate();
|
||||
}
|
||||
|
||||
public void addOrRemoveBreakpointAtCurrentLine() {
|
||||
int line = LayoutHelper.getLineOfChar(mCodeEditText.getLayout(), mCodeEditText.getSelectionStart());
|
||||
if (line < 0 || line >= mCodeEditText.getLayout().getLineCount())
|
||||
return;
|
||||
addOrRemoveBreakpoint(line);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int codeWidth = getWidth() - getPaddingLeft() - getPaddingRight();
|
||||
@ -340,4 +368,14 @@ public class CodeEditor extends HVScrollView {
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
public static class Breakpoint {
|
||||
|
||||
public int line;
|
||||
public boolean enabled = true;
|
||||
|
||||
public Breakpoint(int line) {
|
||||
this.line = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ public class Theme {
|
||||
private int mImeBarForegroundColor = Color.WHITE;
|
||||
private EditorTheme mEditorTheme;
|
||||
private int mLineHighlightBackground;
|
||||
private int mBreakpointColor;
|
||||
private int mDebuggingLineBackground;
|
||||
|
||||
public Theme(EditorTheme theme) {
|
||||
mEditorTheme = theme;
|
||||
@ -34,6 +36,8 @@ public class Theme {
|
||||
mImeBarBackgroundColor = parseColor(theme.getEditorColors().getImeBackgroundColor(), mImeBarBackgroundColor);
|
||||
mImeBarForegroundColor = parseColor(theme.getEditorColors().getImeForegroundColor(), mImeBarForegroundColor);
|
||||
mLineHighlightBackground = parseColor(theme.getEditorColors().getLineHighlightBackground(), mLineHighlightBackground);
|
||||
mDebuggingLineBackground = parseColor(theme.getEditorColors().getDebuggingLineBackground(), mDebuggingLineBackground);
|
||||
mBreakpointColor = parseColor(theme.getEditorColors().getBreakpointForeground(), mBackgroundColor);
|
||||
|
||||
for (TokenColor tokenColor : theme.getTokenColors()) {
|
||||
String foregroundStr = tokenColor.getSettings().getForeground();
|
||||
@ -141,4 +145,11 @@ public class Theme {
|
||||
}
|
||||
|
||||
|
||||
public int getBreakpointColor() {
|
||||
return mBreakpointColor;
|
||||
}
|
||||
|
||||
public int getDebuggingLineBackgroundColor() {
|
||||
return mDebuggingLineBackground;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,163 @@
|
||||
package org.autojs.autojs.ui.edit.toolbar;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.rhino.debug.Dim;
|
||||
import com.stardust.autojs.rhino.debug.DebugCallback;
|
||||
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.ui.edit.EditorView;
|
||||
import org.autojs.autojs.ui.edit.editor.CodeEditor;
|
||||
import org.mozilla.javascript.ContextFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@EFragment(R.layout.fragment_debug_toolbar)
|
||||
public class DebugToolbarFragment extends ToolbarFragment implements DebugCallback {
|
||||
|
||||
private static final String LOG_TAG = "DebugToolbarFragment";
|
||||
private Dim mDim;
|
||||
private EditorView mEditorView;
|
||||
private Handler mHandler;
|
||||
|
||||
public DebugToolbarFragment() {
|
||||
Log.d(LOG_TAG, "DebugToolbarFragment()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mHandler = new Handler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mEditorView = findEditorView(view);
|
||||
ScriptExecution scriptExecution = mEditorView.getScriptExecution();
|
||||
if (scriptExecution != null) {
|
||||
mDim = (Dim) scriptExecution.getEngine().getTag(Dim.TAG);
|
||||
}
|
||||
if (mDim == null) {
|
||||
mDim = new Dim();
|
||||
mDim.setBreak();
|
||||
mDim.setBreakOnExceptions(true);
|
||||
mDim.attachTo(AutoJs.getInstance().getScriptEngineService(), ContextFactory.getGlobal());
|
||||
mDim.setGuiCallback(this);
|
||||
setInterrupted(false);
|
||||
mEditorView.run();
|
||||
} else {
|
||||
mDim.setGuiCallback(this);
|
||||
}
|
||||
Log.d(LOG_TAG, "onViewCreated");
|
||||
}
|
||||
|
||||
private void setInterrupted(boolean interrupted) {
|
||||
setMenuItemStatus(R.id.step_into, interrupted);
|
||||
setMenuItemStatus(R.id.step_over, interrupted);
|
||||
setMenuItemStatus(R.id.step_out, interrupted);
|
||||
setMenuItemStatus(R.id.resume_script, interrupted);
|
||||
if (!interrupted) {
|
||||
mEditorView.getEditor().setDebuggingLine(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public void detachDebugger() {
|
||||
mDim.detach();
|
||||
mDim.setGuiCallback(null);
|
||||
}
|
||||
|
||||
@Click(R.id.step_over)
|
||||
void stepOver() {
|
||||
setInterrupted(false);
|
||||
mDim.setReturnValue(Dim.STEP_OVER);
|
||||
}
|
||||
|
||||
@Click(R.id.step_into)
|
||||
void stepInto() {
|
||||
setInterrupted(false);
|
||||
mDim.setReturnValue(Dim.STEP_INTO);
|
||||
}
|
||||
|
||||
@Click(R.id.step_out)
|
||||
void stepOut() {
|
||||
setInterrupted(false);
|
||||
mDim.setReturnValue(Dim.STEP_OUT);
|
||||
}
|
||||
|
||||
@Click(R.id.stop_script)
|
||||
void stopScript() {
|
||||
mEditorView.forceStop();
|
||||
}
|
||||
|
||||
@Click(R.id.resume_script)
|
||||
void resumeScript() {
|
||||
setInterrupted(false);
|
||||
mDim.setReturnValue(Dim.GO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSourceText(Dim.SourceInfo sourceInfo) {
|
||||
Log.d(LOG_TAG, "updateSourceText: url = " + sourceInfo.url());
|
||||
if (!sourceInfo.url().equals(mEditorView.getFile().toString())) {
|
||||
return;
|
||||
}
|
||||
sourceInfo.removeAllBreakpoints();
|
||||
for (CodeEditor.Breakpoint breakpoint : mEditorView.getEditor().getBreakpoints().values()) {
|
||||
int line = breakpoint.line + 1;
|
||||
if (sourceInfo.breakableLine(line)) {
|
||||
sourceInfo.breakpoint(line, breakpoint.enabled);
|
||||
Log.d(LOG_TAG, "not breakable: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterInterrupt(Dim.StackFrame stackFrame, String threadName, String s1) {
|
||||
Log.d(LOG_TAG, "enterInterrupt: threadName = " + threadName + ", url = " + stackFrame.getUrl() + ", line = " + stackFrame.getLineNumber());
|
||||
if (stackFrame.getUrl().equals(mEditorView.getFile().toString())) {
|
||||
final int line = stackFrame.getLineNumber() - 1;
|
||||
mHandler.post(() -> {
|
||||
mEditorView.getEditor().setDebuggingLine(line);
|
||||
setInterrupted(true);
|
||||
});
|
||||
|
||||
} else {
|
||||
mHandler.post(this::resumeScript);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGuiEventThread() {
|
||||
return Looper.getMainLooper() == Looper.myLooper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchNextGuiEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAttachDebugger(RhinoJavaScriptEngine engine) {
|
||||
ScriptExecution execution = mEditorView.getScriptExecution();
|
||||
return execution != null && execution.getId() == engine.getId();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getMenuItemIds() {
|
||||
return Arrays.asList(R.id.step_over, R.id.step_into, R.id.step_out, R.id.resume_script, R.id.stop_script);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package org.autojs.autojs.ui.edit.toolbar;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import org.androidannotations.annotations.Click;
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
import org.autojs.autojs.R;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@EFragment(R.layout.fragment_normal_toolbar)
|
||||
public class NormalToolbarFragment extends ToolbarFragment {
|
||||
|
||||
|
||||
@Override
|
||||
public List<Integer> getMenuItemIds() {
|
||||
return Arrays.asList(R.id.run, R.id.undo, R.id.redo, R.id.save);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package org.autojs.autojs.ui.edit.toolbar;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
|
||||
import org.androidannotations.annotations.EFragment;
|
||||
import org.autojs.autojs.R;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@EFragment(R.layout.fragment_search_toolbar)
|
||||
public class SearchToolbarFragment extends ToolbarFragment {
|
||||
|
||||
public static final String ARGUMENT_SHOW_REPLACE_ITEM = "show_replace_item";
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
boolean showReplaceItem = getArguments().getBoolean(ARGUMENT_SHOW_REPLACE_ITEM, false);
|
||||
view.findViewById(R.id.replace).setVisibility(showReplaceItem ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getMenuItemIds() {
|
||||
return Arrays.asList(R.id.replace, R.id.find_next, R.id.find_prev, R.id.cancel_search);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package org.autojs.autojs.ui.edit.toolbar;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.View;
|
||||
|
||||
import org.autojs.autojs.ui.edit.EditorView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ToolbarFragment extends Fragment implements View.OnClickListener {
|
||||
|
||||
public interface OnMenuItemClickListener {
|
||||
void onToolbarMenuItemClick(int id);
|
||||
}
|
||||
|
||||
private OnMenuItemClickListener mOnMenuItemClickListener;
|
||||
private List<Integer> mMenuItemIds;
|
||||
|
||||
public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
|
||||
mOnMenuItemClickListener = listener;
|
||||
}
|
||||
|
||||
public abstract List<Integer> getMenuItemIds();
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
updateMenuItemStatus(view);
|
||||
}
|
||||
|
||||
protected EditorView findEditorView(View view) {
|
||||
while (!(view instanceof EditorView) && view.getParent() != null) {
|
||||
view = (View) view.getParent();
|
||||
}
|
||||
if (!(view instanceof EditorView)) {
|
||||
throw new IllegalStateException("cannot find EditorView from child: " + view);
|
||||
}
|
||||
return (EditorView) view;
|
||||
}
|
||||
|
||||
|
||||
private void updateMenuItemStatus(View rootView) {
|
||||
if (rootView == null) {
|
||||
return;
|
||||
}
|
||||
EditorView editorView = findEditorView(rootView);
|
||||
if (mMenuItemIds == null) {
|
||||
mMenuItemIds = getMenuItemIds();
|
||||
}
|
||||
for (int id : mMenuItemIds) {
|
||||
View view = rootView.findViewById(id);
|
||||
view.setOnClickListener(this);
|
||||
view.setEnabled(editorView.getMenuItemStatus(id, view.isEnabled()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mOnMenuItemClickListener != null) {
|
||||
mOnMenuItemClickListener.onToolbarMenuItemClick(view.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public void setMenuItemStatus(int id, boolean enabled) {
|
||||
if (mMenuItemIds == null) {
|
||||
mMenuItemIds = getMenuItemIds();
|
||||
}
|
||||
if (!mMenuItemIds.contains(id)) {
|
||||
return;
|
||||
}
|
||||
View rootView = getView();
|
||||
if (rootView == null) {
|
||||
return;
|
||||
}
|
||||
View view = rootView.findViewById(id);
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
view.setEnabled(enabled);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,18 +1,13 @@
|
||||
package org.autojs.autojs.ui.main.task;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.engine.ScriptEngineFactory;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.script.AutoFileSource;
|
||||
import com.stardust.autojs.script.JavaScriptSource;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
import org.autojs.autojs.App;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.timing.TimedTask;
|
||||
import org.autojs.autojs.timing.TimedTaskManager;
|
||||
@ -23,7 +18,7 @@ import org.joda.time.format.DateTimeFormat;
|
||||
* Created by Stardust on 2017/11/28.
|
||||
*/
|
||||
|
||||
public abstract class Task {
|
||||
public abstract class Task {
|
||||
|
||||
public abstract String getName();
|
||||
|
||||
@ -78,46 +73,37 @@ public abstract class Task {
|
||||
}
|
||||
|
||||
public static class RunningTask extends Task {
|
||||
private final ScriptEngine mScriptEngine;
|
||||
private final ScriptExecution mScriptExecution;
|
||||
|
||||
public RunningTask(ScriptEngine scriptEngine) {
|
||||
mScriptEngine = scriptEngine;
|
||||
public RunningTask(ScriptExecution scriptExecution) {
|
||||
mScriptExecution = scriptExecution;
|
||||
}
|
||||
|
||||
public ScriptEngine getScriptEngine() {
|
||||
return mScriptEngine;
|
||||
public ScriptExecution getScriptExecution() {
|
||||
return mScriptExecution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
ScriptSource source = (ScriptSource) mScriptEngine.getTag(ScriptEngine.TAG_SOURCE);
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return source.getName();
|
||||
return mScriptExecution.getSource().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDesc() {
|
||||
ScriptSource source = (ScriptSource) mScriptEngine.getTag(ScriptEngine.TAG_SOURCE);
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return source.toString();
|
||||
return mScriptExecution.getSource().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
mScriptEngine.forceStop();
|
||||
ScriptEngine engine = mScriptExecution.getEngine();
|
||||
if (engine != null) {
|
||||
engine.forceStop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
ScriptSource source = (ScriptSource) mScriptEngine.getTag(ScriptEngine.TAG_SOURCE);
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return source.getEngineName();
|
||||
return mScriptExecution.getSource().getEngineName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,12 +4,15 @@ import android.content.Context;
|
||||
|
||||
import com.bignerdranch.expandablerecyclerview.model.Parent;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.timing.TimedTask;
|
||||
import org.autojs.autojs.timing.TimedTaskManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@ -98,20 +101,20 @@ public abstract class TaskGroup implements Parent<Task> {
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
Set<ScriptEngine> scriptEngines = AutoJs.getInstance().getScriptEngineService().getEngines();
|
||||
Collection<ScriptExecution> executions = AutoJs.getInstance().getScriptEngineService().getScriptExecutions();
|
||||
mTasks.clear();
|
||||
for (ScriptEngine engine : scriptEngines) {
|
||||
mTasks.add(new Task.RunningTask(engine));
|
||||
for (ScriptExecution execution : executions) {
|
||||
mTasks.add(new Task.RunningTask(execution));
|
||||
}
|
||||
}
|
||||
|
||||
public int addTask(ScriptEngine engine) {
|
||||
public int addTask(ScriptExecution engine) {
|
||||
int pos = mTasks.size();
|
||||
mTasks.add(new Task.RunningTask(engine));
|
||||
return pos;
|
||||
}
|
||||
|
||||
public int removeTask(ScriptEngine engine) {
|
||||
public int removeTask(ScriptExecution engine) {
|
||||
int i = indexOf(engine);
|
||||
if (i >= 0) {
|
||||
mTasks.remove(i);
|
||||
@ -119,9 +122,9 @@ public abstract class TaskGroup implements Parent<Task> {
|
||||
return i;
|
||||
}
|
||||
|
||||
public int indexOf(ScriptEngine engine) {
|
||||
public int indexOf(ScriptExecution engine) {
|
||||
for (int i = 0; i < mTasks.size(); i++) {
|
||||
if (((Task.RunningTask) mTasks.get(i)).getScriptEngine().equals(engine)) {
|
||||
if (((Task.RunningTask) mTasks.get(i)).getScriptExecution().equals(engine)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
|
||||
|
||||
import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
|
||||
@ -25,6 +26,7 @@ import com.stardust.autojs.execution.ScriptExecutionListener;
|
||||
import com.stardust.autojs.execution.SimpleScriptExecutionListener;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.script.AutoFileSource;
|
||||
|
||||
import org.autojs.autojs.R;
|
||||
import org.autojs.autojs.autojs.AutoJs;
|
||||
import org.autojs.autojs.storage.database.ModelChange;
|
||||
@ -32,6 +34,7 @@ import org.autojs.autojs.timing.TaskReceiver;
|
||||
import org.autojs.autojs.timing.TimedTask;
|
||||
import org.autojs.autojs.timing.TimedTaskManager;
|
||||
import org.autojs.autojs.ui.timing.TimedTaskSettingActivity_;
|
||||
|
||||
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -47,7 +50,7 @@ import io.reactivex.disposables.Disposable;
|
||||
* Created by Stardust on 2017/3/24.
|
||||
*/
|
||||
|
||||
public class TaskListRecyclerView extends ThemeColorRecyclerView implements ScriptEngineManager.EngineLifecycleCallback {
|
||||
public class TaskListRecyclerView extends ThemeColorRecyclerView {
|
||||
|
||||
|
||||
private static final String LOG_TAG = "TaskListRecyclerView";
|
||||
@ -61,15 +64,28 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
|
||||
private ScriptExecutionListener mScriptExecutionListener = new SimpleScriptExecutionListener() {
|
||||
@Override
|
||||
public void onStart(final ScriptExecution execution) {
|
||||
post(() -> {
|
||||
int position = mRunningTaskGroup.indexOf(execution.getEngine());
|
||||
if (position >= 0) {
|
||||
mAdapter.notifyChildChanged(0, position);
|
||||
post(()-> mAdapter.notifyChildInserted(0, mRunningTaskGroup.addTask(execution)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(ScriptExecution execution, Object result) {
|
||||
onFinish(execution);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(ScriptExecution execution, Exception e) {
|
||||
onFinish(execution);
|
||||
}
|
||||
|
||||
private void onFinish(ScriptExecution execution){
|
||||
post(()->{
|
||||
final int i = mRunningTaskGroup.removeTask(execution);
|
||||
if (i >= 0) {
|
||||
mAdapter.notifyChildRemoved(0, i);
|
||||
} else {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -116,7 +132,6 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mScriptEngineService.registerEngineLifecycleCallback(this);
|
||||
AutoJs.getInstance().getScriptEngineService().registerGlobalScriptExecutionListener(mScriptExecutionListener);
|
||||
mTimedTaskChangeDisposable = TimedTaskManager.getInstance().getTimeTaskChanges()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -134,7 +149,6 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mScriptEngineService.unregisterEngineLifecycleCallback(this);
|
||||
AutoJs.getInstance().getScriptEngineService().unregisterGlobalScriptExecutionListener(mScriptExecutionListener);
|
||||
mTimedTaskChangeDisposable.dispose();
|
||||
}
|
||||
@ -162,26 +176,6 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEngineCreate(final ScriptEngine engine) {
|
||||
post(() ->
|
||||
mAdapter.notifyChildInserted(0, mRunningTaskGroup.addTask(engine))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEngineRemove(final ScriptEngine engine) {
|
||||
post(() -> {
|
||||
final int i = mRunningTaskGroup.removeTask(engine);
|
||||
if (i >= 0) {
|
||||
mAdapter.notifyChildRemoved(0, i);
|
||||
} else {
|
||||
refresh();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private class Adapter extends ExpandableRecyclerAdapter<TaskGroup, Task, TaskGroupViewHolder, TaskViewHolder> {
|
||||
|
||||
public Adapter(@NonNull List<TaskGroup> parentList) {
|
||||
|
||||
BIN
app/src/main/res/drawable-xhdpi/ic_debug.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_debug.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
app/src/main/res/drawable/ic_debug_step_into.png
Normal file
BIN
app/src/main/res/drawable/ic_debug_step_into.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable/ic_debug_step_out.png
Normal file
BIN
app/src/main/res/drawable/ic_debug_step_out.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable/ic_debug_step_over.png
Normal file
BIN
app/src/main/res/drawable/ic_debug_step_over.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
@ -5,6 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollHorizontally="true"
|
||||
android:imeOptions="flagNoExtractUi"
|
||||
android:textColor="@android:color/transparent"
|
||||
android:textCursorDrawable="@drawable/code_edit_text_cursor"
|
||||
android:textSize="15sp"/>
|
||||
|
||||
@ -19,89 +19,11 @@
|
||||
android:title="@string/_app_name"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
<com.stardust.widget.ViewSwitcher
|
||||
android:id="@+id/toolbar_switcher"
|
||||
<FrameLayout
|
||||
android:id="@+id/toolbar_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/run"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_play_arrow_white_48dp"
|
||||
app:icon_color="@android:color/white"
|
||||
app:text="@string/text_run"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/undo"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_undo_white_48dp"
|
||||
app:text="@string/text_undo"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/redo"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_redo_white_48dp"
|
||||
app:text="@string/text_redo"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/save"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false"
|
||||
app:icon="@drawable/ic_save_white_48dp"
|
||||
app:text="@string/text_save"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/replace"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_ali_replace"
|
||||
app:text="@string/text_replace"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/find_prev"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_ali_up"
|
||||
app:text="@string/text_find_prev"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/find_next"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_ali_down"
|
||||
app:text="@string/text_find_next"/>
|
||||
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_close_white_48dp"
|
||||
app:text="@string/text_cancel"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</com.stardust.widget.ViewSwitcher>
|
||||
android:layout_gravity="right"/>
|
||||
|
||||
</com.stardust.theme.widget.ThemeColorToolbar>
|
||||
|
||||
|
||||
46
app/src/main/res/layout/fragment_debug_toolbar.xml
Normal file
46
app/src/main/res/layout/fragment_debug_toolbar.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/step_over"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_debug_step_over"
|
||||
app:text="@string/text_debug_step_over"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/step_into"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_debug_step_into"
|
||||
app:text="@string/text_debug_step_into"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/step_out"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_debug_step_out"
|
||||
app:text="@string/text_debug_step_out"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/resume_script"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_play_arrow_white_48dp"
|
||||
app:text="@string/text_debug_resume_script"/>
|
||||
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/stop_script"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_close_white_48dp"
|
||||
app:text="@string/text_stop"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
40
app/src/main/res/layout/fragment_normal_toolbar.xml
Normal file
40
app/src/main/res/layout/fragment_normal_toolbar.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/run"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_play_arrow_white_48dp"
|
||||
app:icon_color="@android:color/white"
|
||||
app:text="@string/text_run"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/undo"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_undo_white_48dp"
|
||||
app:text="@string/text_undo"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/redo"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_redo_white_48dp"
|
||||
app:text="@string/text_redo"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/save"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false"
|
||||
app:icon="@drawable/ic_save_white_48dp"
|
||||
app:text="@string/text_save"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
39
app/src/main/res/layout/fragment_search_toolbar.xml
Normal file
39
app/src/main/res/layout/fragment_search_toolbar.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/replace"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_ali_replace"
|
||||
app:text="@string/text_replace"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/find_prev"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_ali_up"
|
||||
app:text="@string/text_find_prev"/>
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/find_next"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_ali_down"
|
||||
app:text="@string/text_find_next"/>
|
||||
|
||||
|
||||
<org.autojs.autojs.ui.widget.ToolbarMenuItem
|
||||
android:id="@+id/cancel_search"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_close_white_48dp"
|
||||
app:text="@string/text_cancel"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@ -79,6 +79,24 @@
|
||||
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:title="@string/text_debug"
|
||||
app:showAsAction="never">
|
||||
|
||||
<menu>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_breakpoint"
|
||||
android:title="@string/text_set_breakpoint"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_launch_debugger"
|
||||
android:title="@string/text_launch_debugger"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_build_apk"
|
||||
|
||||
@ -359,4 +359,12 @@
|
||||
<string name="key_script_dir_path">key_script_dir_path</string>
|
||||
<string name="default_value_script_dir_path">/脚本/</string>
|
||||
<string name="text_error_copy_file" formatted="true">发生错误: %s</string>
|
||||
<string name="text_debug">调试</string>
|
||||
<string name="text_set_breakpoint">断点</string>
|
||||
<string name="text_launch_debugger">启动调试</string>
|
||||
<string name="text_debug_step_out">跳出</string>
|
||||
<string name="text_debug_step_into">进入</string>
|
||||
<string name="text_debug_step_over">单步</string>
|
||||
<string name="text_debug_resume_script">继续</string>
|
||||
<string name="text_stop">停止</string>
|
||||
</resources>
|
||||
|
||||
@ -101,6 +101,7 @@ public abstract class AutoJs {
|
||||
engine.setRuntime(createRuntime());
|
||||
return engine;
|
||||
});
|
||||
LoopBasedJavaScriptEngine.initEngine();
|
||||
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, () -> new RootAutomatorEngine(mContext));
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.stardust.autojs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
@ -24,12 +26,18 @@ import com.stardust.util.UiHandler;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.mozilla.javascript.RhinoException;
|
||||
import org.mozilla.javascript.ScriptStackElement;
|
||||
import org.mozilla.javascript.WrappedException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PipedReader;
|
||||
import java.io.PipedWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ -83,8 +91,16 @@ public class ScriptEngineService {
|
||||
private UiHandler mUiHandler;
|
||||
private final Console mGlobalConsole;
|
||||
private final ScriptEngineManager mScriptEngineManager;
|
||||
private final EngineLifecycleObserver mEngineLifecycleObserver = new EngineLifecycleObserver();
|
||||
private final EngineLifecycleObserver mEngineLifecycleObserver = new EngineLifecycleObserver() {
|
||||
|
||||
@Override
|
||||
public void onEngineRemove(ScriptEngine engine) {
|
||||
mScriptExecutions.remove(engine.getId());
|
||||
super.onEngineRemove(engine);
|
||||
}
|
||||
};
|
||||
private ScriptExecutionObserver mScriptExecutionObserver = new ScriptExecutionObserver();
|
||||
private LinkedHashMap<Integer, ScriptExecution> mScriptExecutions = new LinkedHashMap<>();
|
||||
|
||||
ScriptEngineService(ScriptEngineServiceBuilder builder) {
|
||||
mUiHandler = builder.mUiHandler;
|
||||
@ -119,6 +135,12 @@ public class ScriptEngineService {
|
||||
}
|
||||
|
||||
public ScriptExecution execute(ScriptExecutionTask task) {
|
||||
ScriptExecution execution = executeInternal(task);
|
||||
mScriptExecutions.put(execution.getId(), execution);
|
||||
return execution;
|
||||
}
|
||||
|
||||
private ScriptExecution executeInternal(ScriptExecutionTask task) {
|
||||
if (task.getListener() != null) {
|
||||
task.setExecutionListener(new ScriptExecutionObserver.Wrapper(mScriptExecutionObserver, task.getListener()));
|
||||
} else {
|
||||
@ -185,6 +207,18 @@ public class ScriptEngineService {
|
||||
return mScriptEngineManager.getEngines();
|
||||
}
|
||||
|
||||
public Collection<ScriptExecution> getScriptExecutions() {
|
||||
return mScriptExecutions.values();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ScriptExecution getScriptExecution(int id) {
|
||||
if (id == ScriptExecution.NO_ID) {
|
||||
return null;
|
||||
}
|
||||
return mScriptExecutions.get(id);
|
||||
}
|
||||
|
||||
private static class EngineLifecycleObserver implements ScriptEngineManager.EngineLifecycleCallback {
|
||||
|
||||
private final Set<ScriptEngineManager.EngineLifecycleCallback> mEngineLifecycleCallbacks = new LinkedHashSet<>();
|
||||
@ -245,7 +279,17 @@ public class ScriptEngineService {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getScriptTrace(Exception e) {
|
||||
public static String getScriptTrace(Exception e) {
|
||||
StringBuilder scriptTrace = new StringBuilder();
|
||||
if (e instanceof RhinoException) {
|
||||
RhinoException rhinoException = (RhinoException) e;
|
||||
scriptTrace.append(rhinoException.details()).append("\n");
|
||||
for (ScriptStackElement element : rhinoException.getScriptStack()) {
|
||||
element.renderV8Style(scriptTrace);
|
||||
scriptTrace.append("\n");
|
||||
}
|
||||
scriptTrace.append("- - - - - - - - - - -\n");
|
||||
}
|
||||
try {
|
||||
PipedReader reader = new PipedReader(8192);
|
||||
PrintWriter writer = new PrintWriter(new PipedWriter(reader));
|
||||
@ -253,10 +297,9 @@ public class ScriptEngineService {
|
||||
writer.close();
|
||||
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||
String line;
|
||||
StringBuilder scriptTrace = new StringBuilder(TextUtils.toEmptyIfNull(e.getMessage()));
|
||||
//scriptTrace.append(TextUtils.toEmptyIfNull(e.getMessage()));
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
if (line.trim().startsWith("at script"))
|
||||
scriptTrace.append("\n").append(line);
|
||||
scriptTrace.append("\n").append(line);
|
||||
}
|
||||
return scriptTrace.toString();
|
||||
} catch (IOException e1) {
|
||||
|
||||
@ -4,6 +4,7 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.CallSuper;
|
||||
|
||||
import com.stardust.autojs.ScriptEngineService;
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
import com.stardust.autojs.runtime.ScriptBridges;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
@ -48,7 +49,7 @@ public class TimerThread extends ThreadCompat {
|
||||
Looper.loop();
|
||||
} catch (Exception e) {
|
||||
if (!ScriptInterruptedException.causedByInterrupted(e)) {
|
||||
mRuntime.console.error(Thread.currentThread().toString() + ": " + e);
|
||||
mRuntime.console.error(Thread.currentThread().toString() + ": " + ScriptEngineService.getScriptTrace(e));
|
||||
}
|
||||
} finally {
|
||||
onExit();
|
||||
|
||||
@ -176,7 +176,6 @@ public class DynamicLayoutInflater {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public View inflate(Node node, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = doInflation(node, parent, attachToParent);
|
||||
if (view != null && view instanceof ShouldCallOnFinishInflate) {
|
||||
|
||||
@ -86,5 +86,9 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
|
||||
super.init();
|
||||
}
|
||||
|
||||
public static void initEngine(){
|
||||
RhinoJavaScriptEngine.initEngine();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.stardust.autojs.engine;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import com.stardust.autojs.BuildConfig;
|
||||
import com.stardust.autojs.rhino.AndroidContextFactory;
|
||||
import com.stardust.autojs.rhino.NativeJavaClassWithPrototype;
|
||||
@ -33,6 +34,7 @@ import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -43,10 +45,13 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
|
||||
public static final String SOURCE_NAME_INIT = "<init>";
|
||||
|
||||
private static final String LOG_TAG = "RhinoJavaScriptEngine";
|
||||
|
||||
private static int contextCount = 0;
|
||||
private static StringScriptSource sInitScript;
|
||||
private static final ConcurrentHashMap<Context, RhinoJavaScriptEngine> sContextEngineMap = new ConcurrentHashMap<>();
|
||||
|
||||
private Context mContext;
|
||||
private Scriptable mScriptable;
|
||||
@ -69,7 +74,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
Reader reader = source.getNonNullScriptReader();
|
||||
try {
|
||||
reader = preprocess(reader);
|
||||
return mContext.evaluateReader(mScriptable, reader, "<" + source.getName() + ">", 1, null);
|
||||
return mContext.evaluateReader(mScriptable, reader, source.toString(), 1, null);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
@ -90,6 +95,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
public synchronized void destroy() {
|
||||
super.destroy();
|
||||
Log.d(LOG_TAG, "on destroy");
|
||||
sContextEngineMap.remove(getContext());
|
||||
Context.exit();
|
||||
contextCount--;
|
||||
Log.d(LOG_TAG, "contextCount = " + contextCount);
|
||||
@ -105,7 +111,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
mThread = Thread.currentThread();
|
||||
ScriptableObject.putProperty(mScriptable, "__engine__", this);
|
||||
initRequireBuilder(mContext, mScriptable);
|
||||
mContext.evaluateString(mScriptable, getInitScript().getScript(), "<init>", 1, null);
|
||||
mContext.evaluateString(mScriptable, getInitScript().getScript(), SOURCE_NAME_INIT, 1, null);
|
||||
}
|
||||
|
||||
private JavaScriptSource getInitScript() {
|
||||
@ -148,12 +154,10 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
}
|
||||
|
||||
public Context createContext() {
|
||||
if (!ContextFactory.hasExplicitGlobal()) {
|
||||
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mAndroidContext.getCacheDir(), "classes")));
|
||||
}
|
||||
Context context = new RhinoAndroidHelper(mAndroidContext).enterContext();
|
||||
contextCount++;
|
||||
setupContext(context);
|
||||
sContextEngineMap.put(context, this);
|
||||
return context;
|
||||
}
|
||||
|
||||
@ -164,6 +168,17 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
context.setWrapFactory(new WrapFactory());
|
||||
}
|
||||
|
||||
public static void initEngine() {
|
||||
if (!ContextFactory.hasExplicitGlobal()) {
|
||||
android.content.Context context = GlobalAppContext.get();
|
||||
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(context.getCacheDir(), "classes")));
|
||||
}
|
||||
}
|
||||
|
||||
public static RhinoJavaScriptEngine getEngineOfContext(Context context) {
|
||||
return sContextEngineMap.get(context);
|
||||
}
|
||||
|
||||
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
|
||||
|
||||
|
||||
|
||||
@ -2,17 +2,18 @@ package com.stardust.autojs.engine;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
|
||||
import com.stardust.autojs.runtime.exception.ScriptException;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/2.
|
||||
* <p>
|
||||
* <p>
|
||||
* A ScriptEngine is created by {@link ScriptEngineManager#createEngine(String)} ()}, and then can be
|
||||
* A ScriptEngine is created by {@link ScriptEngineManager#createEngine(String, int)} ()}, and then can be
|
||||
* used to execute script with {@link ScriptEngine#execute(ScriptSource)} in the **same** thread.
|
||||
* When the execution finish successfully, the engine should be destroy in the thread that created it.
|
||||
* <p>
|
||||
@ -46,6 +47,9 @@ public interface ScriptEngine<S extends ScriptSource> {
|
||||
|
||||
Exception getUncaughtException();
|
||||
|
||||
void setId(int id);
|
||||
|
||||
int getId();
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@ -68,7 +72,7 @@ public interface ScriptEngine<S extends ScriptSource> {
|
||||
private OnDestroyListener mOnDestroyListener;
|
||||
private boolean mDestroyed = false;
|
||||
private Exception mUncaughtException;
|
||||
|
||||
private volatile AtomicInteger mId = new AtomicInteger(ScriptExecution.NO_ID);
|
||||
|
||||
@Override
|
||||
public synchronized void setTag(String key, Object value) {
|
||||
@ -116,5 +120,15 @@ public interface ScriptEngine<S extends ScriptSource> {
|
||||
public Exception getUncaughtException() {
|
||||
return mUncaughtException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
mId.compareAndSet(ScriptExecution.NO_ID, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return mId.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.util.Supplier;
|
||||
|
||||
@ -96,37 +97,34 @@ public class ScriptEngineManager {
|
||||
|
||||
|
||||
@Nullable
|
||||
public ScriptEngine createEngine(String name) {
|
||||
public ScriptEngine createEngine(String name, int id) {
|
||||
Supplier<ScriptEngine> s = mEngineSuppliers.get(name);
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
ScriptEngine engine = s.get();
|
||||
engine.setId(id);
|
||||
putProperties(engine);
|
||||
addEngine(engine);
|
||||
return engine;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ScriptEngine createEngineOfSource(ScriptSource source) {
|
||||
return createEngine(source.getEngineName());
|
||||
public ScriptEngine createEngineOfSource(ScriptSource source, int id) {
|
||||
return createEngine(source.getEngineName(), id);
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
public ScriptEngine createEngineByNameOrThrow(String name) {
|
||||
ScriptEngine engine = createEngine(name);
|
||||
public ScriptEngine createEngineOfSourceOrThrow(ScriptSource source, int id) {
|
||||
ScriptEngine engine = createEngineOfSource(source, id);
|
||||
if (engine == null)
|
||||
throw new ScriptEngineFactory.EngineNotFoundException("name: " + name);
|
||||
throw new ScriptEngineFactory.EngineNotFoundException("source: " + source.toString());
|
||||
return engine;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ScriptEngine createEngineOfSourceOrThrow(ScriptSource source) {
|
||||
ScriptEngine engine = createEngineOfSource(source);
|
||||
if (engine == null)
|
||||
throw new ScriptEngineFactory.EngineNotFoundException("source: " + source.toString());
|
||||
return engine;
|
||||
return createEngineOfSourceOrThrow(source, ScriptExecution.NO_ID);
|
||||
}
|
||||
|
||||
public void registerEngine(String name, Supplier<ScriptEngine> supplier) {
|
||||
|
||||
@ -77,4 +77,14 @@ public class ScriptEngineProxy<S extends ScriptSource> implements ScriptEngine<S
|
||||
public void init() {
|
||||
mScriptEngine.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return mScriptEngine.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
mScriptEngine.setId(id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
||||
}
|
||||
|
||||
public Object execute() {
|
||||
mScriptEngine = mScriptEngineManager.createEngineOfSourceOrThrow(getSource());
|
||||
mScriptEngine = mScriptEngineManager.createEngineOfSourceOrThrow(getSource(), getId());
|
||||
return execute(mScriptEngine);
|
||||
}
|
||||
|
||||
|
||||
@ -4,12 +4,17 @@ import com.stardust.autojs.engine.ScriptEngine;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/3.
|
||||
*/
|
||||
|
||||
public interface ScriptExecution {
|
||||
|
||||
int NO_ID = -1;
|
||||
|
||||
ScriptEngine getEngine();
|
||||
|
||||
ScriptSource getSource();
|
||||
@ -18,12 +23,18 @@ public interface ScriptExecution {
|
||||
|
||||
ExecutionConfig getConfig();
|
||||
|
||||
int getId();
|
||||
|
||||
abstract class AbstractScriptExecution implements ScriptExecution {
|
||||
|
||||
private static AtomicInteger sMaxId = new AtomicInteger(0);
|
||||
|
||||
protected ScriptExecutionTask mScriptExecutionTask;
|
||||
protected int mId;
|
||||
|
||||
public AbstractScriptExecution(ScriptExecutionTask task) {
|
||||
mScriptExecutionTask = task;
|
||||
mId = sMaxId.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,5 +54,23 @@ public interface ScriptExecution {
|
||||
public ExecutionConfig getConfig() {
|
||||
return mScriptExecutionTask.getConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AbstractScriptExecution that = (AbstractScriptExecution) o;
|
||||
return mId == that.mId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
package com.stardust.autojs.rhino.debug;
|
||||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
|
||||
import com.stardust.autojs.engine.ScriptEngine;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
|
||||
/**
|
||||
* Interface for communication between the debugger and its GUI. This
|
||||
* should be implemented by the GUI.
|
||||
*/
|
||||
public interface DebugCallback {
|
||||
|
||||
/**
|
||||
* Called when the source text of some script has been changed.
|
||||
*/
|
||||
void updateSourceText(Dim.SourceInfo sourceInfo);
|
||||
|
||||
/**
|
||||
* Called when the interrupt loop has been entered.
|
||||
*/
|
||||
void enterInterrupt(Dim.StackFrame lastFrame,
|
||||
String threadTitle,
|
||||
String alertMessage);
|
||||
|
||||
/**
|
||||
* Returns whether the current thread is the GUI's event thread.
|
||||
* This information is required to avoid blocking the event thread
|
||||
* from the debugger.
|
||||
*/
|
||||
boolean isGuiEventThread();
|
||||
|
||||
/**
|
||||
* Processes the next GUI event. This manual pumping of GUI events
|
||||
* is necessary when the GUI event thread itself has been stopped.
|
||||
*/
|
||||
void dispatchNextGuiEvent() throws InterruptedException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether the debugger should attach to this engine or not.
|
||||
*/
|
||||
boolean shouldAttachDebugger(RhinoJavaScriptEngine engine);
|
||||
}
|
||||
1560
autojs/src/main/java/com/stardust/autojs/rhino/debug/Dim.java
Normal file
1560
autojs/src/main/java/com/stardust/autojs/rhino/debug/Dim.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -372,7 +372,7 @@ public class ScriptRuntime {
|
||||
try {
|
||||
events.emit("exit");
|
||||
} catch (Exception ignored) {
|
||||
console.error("exception on exit: " + ignored);
|
||||
console.error("exception on exit: " + ScriptEngineService.getScriptTrace(ignored));
|
||||
}
|
||||
ignoresException(threads::shutDownAll);
|
||||
ignoresException(events::recycle);
|
||||
|
||||
@ -3,11 +3,14 @@ package com.stardust.autojs.runtime.exception;
|
||||
import org.mozilla.javascript.EvaluatorException;
|
||||
import org.mozilla.javascript.RhinoException;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/29.
|
||||
*/
|
||||
public class ScriptException extends RuntimeException {
|
||||
|
||||
|
||||
public ScriptException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":401},"path":"commonRelease-4.0.0 Alpha1.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":408},"path":"commonRelease-4.0.2 Alpha3.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
|
||||
@ -10,6 +10,7 @@ import com.stardust.auojs.inrt.BuildConfig;
|
||||
import com.stardust.auojs.inrt.LogActivity;
|
||||
import com.stardust.auojs.inrt.Pref;
|
||||
import com.stardust.auojs.inrt.autojs.AutoJs;
|
||||
import com.stardust.autojs.ScriptEngineService;
|
||||
import com.stardust.autojs.execution.ExecutionConfig;
|
||||
import com.stardust.autojs.execution.ScriptExecution;
|
||||
import com.stardust.autojs.project.ProjectConfig;
|
||||
@ -73,7 +74,7 @@ public class AssetsProjectLauncher {
|
||||
mScriptExecution = AutoJs.getInstance().getScriptEngineService().execute(source, new ExecutionConfig()
|
||||
.executePath(mProjectDir));
|
||||
} catch (Exception e) {
|
||||
AutoJs.getInstance().getGlobalConsole().error(e);
|
||||
AutoJs.getInstance().getGlobalConsole().error(ScriptEngineService.getScriptTrace(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user