imporve code completion
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -48,7 +48,7 @@
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "com.stardust.scriptdroid"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 153
|
||||
versionName "2.0.15 Beta"
|
||||
versionCode 154
|
||||
versionName "2.0.15 Alpha2"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
返回路径path是否是文件夹。
|
||||
|
||||
### files.isDirEmpty(path)
|
||||
### files.isEmptyDir(path)
|
||||
* path \<String\> 路径
|
||||
|
||||
返回文件夹path是否为空文件夹。如果该路径并非文件夹,则直接返回false。
|
||||
|
||||
@@ -1,62 +1,305 @@
|
||||
[ "toast",
|
||||
"app",
|
||||
"launchPackage",
|
||||
"launch",
|
||||
"launchApp",
|
||||
"getPackageName",
|
||||
"openAppSetting",
|
||||
"sleep",
|
||||
"isStopped",
|
||||
"notStopped",
|
||||
"stop",
|
||||
"console",
|
||||
"log",
|
||||
"print",
|
||||
"err",
|
||||
"openConsole",
|
||||
"clearConsole",
|
||||
"shell",
|
||||
"currentPackage",
|
||||
"currentActivity",
|
||||
"back",
|
||||
"home",
|
||||
"powerDialog",
|
||||
"notifications",
|
||||
"quickSettings",
|
||||
"recents",
|
||||
"splitScreen",
|
||||
"click",
|
||||
"longClick",
|
||||
"scrollDown",
|
||||
"scrollUp",
|
||||
"input",
|
||||
"setClip",
|
||||
"SetScreenMetrics",
|
||||
"Tap",
|
||||
"Swipe",
|
||||
"Screencap",
|
||||
"KeyCode",
|
||||
"Home",
|
||||
"Back",
|
||||
"Power",
|
||||
"Up",
|
||||
"Down",
|
||||
"Left",
|
||||
"Right",
|
||||
"OK",
|
||||
"VolumeUp",
|
||||
"VolumeDown",
|
||||
"Menu",
|
||||
"Camera",
|
||||
"Text",
|
||||
"selector",
|
||||
"open",
|
||||
"newInjectableWebClient",
|
||||
"newInjectableWebView",
|
||||
"dialogs",
|
||||
"rawInput",
|
||||
"input",
|
||||
"alert",
|
||||
"confirm",
|
||||
"prompt"
|
||||
]
|
||||
{
|
||||
"global" : {
|
||||
"modules": [
|
||||
"app",
|
||||
"automator",
|
||||
"console",
|
||||
"dialogs",
|
||||
"events",
|
||||
"images",
|
||||
"files",
|
||||
"timers",
|
||||
"ui"
|
||||
],
|
||||
"app": [
|
||||
"launchPackage",
|
||||
"launch",
|
||||
"launchApp",
|
||||
"getPackageName",
|
||||
"openAppSetting"
|
||||
],
|
||||
"automator": [
|
||||
"click",
|
||||
"longClick",
|
||||
"press",
|
||||
"swipe",
|
||||
"gesture",
|
||||
"gestures",
|
||||
"gestureAsync",
|
||||
"gesturesAsync",
|
||||
"scrollDown",
|
||||
"scrollUp",
|
||||
"input",
|
||||
"setText"
|
||||
],
|
||||
"console": [
|
||||
"print",
|
||||
"log",
|
||||
"err",
|
||||
"openConsole",
|
||||
"clearConsole"
|
||||
],
|
||||
"dialogs":[
|
||||
"rawInput",
|
||||
"input",
|
||||
"alert",
|
||||
"confirm",
|
||||
"prompt"
|
||||
],
|
||||
"images": [
|
||||
"requestScreenCapture",
|
||||
"captureScreen",
|
||||
"findColor",
|
||||
"findColorInRegion",
|
||||
"findColorEquals"
|
||||
],
|
||||
"files": [
|
||||
"open"
|
||||
],
|
||||
"selector": [
|
||||
"id",
|
||||
"idContains",
|
||||
"idStartsWith",
|
||||
"idEndsWith",
|
||||
"idMatches",
|
||||
"text",
|
||||
"textContains",
|
||||
"textStartsWith",
|
||||
"textEndsWith",
|
||||
"textMatches",
|
||||
"desc",
|
||||
"descContains",
|
||||
"descStartsWith",
|
||||
"descEndsWith",
|
||||
"descMatches",
|
||||
"className",
|
||||
"classNameContains",
|
||||
"classNameStartsWith",
|
||||
"classNameEndsWith",
|
||||
"classNameMatches",
|
||||
"packageName",
|
||||
"packageNameContains",
|
||||
"packageNameStartsWith",
|
||||
"packageNameEndsWith",
|
||||
"packageNameMatches",
|
||||
"bounds",
|
||||
"boundsInside",
|
||||
"boundsContains",
|
||||
"drawingOrder",
|
||||
"checkable",
|
||||
"checked",
|
||||
"focusable",
|
||||
"focused",
|
||||
"visibleToUser",
|
||||
"accessibilityFocused",
|
||||
"selected",
|
||||
"clickable",
|
||||
"longClickable",
|
||||
"enabled",
|
||||
"password",
|
||||
"scrollable",
|
||||
"editable",
|
||||
"contentInvalid",
|
||||
"contextClickable",
|
||||
"multiLine",
|
||||
"dismissable",
|
||||
"checkable",
|
||||
"checked",
|
||||
"focusable",
|
||||
"focused",
|
||||
"visibleToUser",
|
||||
"accessibilityFocused",
|
||||
"selected",
|
||||
"clickable",
|
||||
"longClickable",
|
||||
"enabled",
|
||||
"password",
|
||||
"scrollable",
|
||||
"editable",
|
||||
"contentInvalid",
|
||||
"contextClickable",
|
||||
"multiLine",
|
||||
"dismissable"
|
||||
],
|
||||
"shell": [
|
||||
"SetScreenMetrics",
|
||||
"Tap",
|
||||
"Swipe",
|
||||
"Screencap",
|
||||
"KeyCode",
|
||||
"Home",
|
||||
"Back",
|
||||
"Power",
|
||||
"Up",
|
||||
"Down",
|
||||
"Left",
|
||||
"Right",
|
||||
"OK",
|
||||
"VolumeUp",
|
||||
"VolumeDown",
|
||||
"Menu",
|
||||
"Camera",
|
||||
"Text"
|
||||
],
|
||||
"timers": [
|
||||
"loop",
|
||||
"setTimeout",
|
||||
"clearTimeout",
|
||||
"setInterval",
|
||||
"clearInterval",
|
||||
"setImmediate",
|
||||
"clearImmediate"
|
||||
],
|
||||
"web": [
|
||||
"newInjectableWebClient",
|
||||
"newInjectableWebView"
|
||||
],
|
||||
"general": [
|
||||
"toast",
|
||||
"toastLog",
|
||||
"sleep",
|
||||
"isStopped",
|
||||
"notStopped",
|
||||
"exit",
|
||||
"setClip",
|
||||
"getClip",
|
||||
"currentPackage",
|
||||
"currentActivity",
|
||||
"waitForActivity",
|
||||
"waitForPackage",
|
||||
"setScreenMetrics"
|
||||
],
|
||||
"variables": [
|
||||
"context",
|
||||
"activity"
|
||||
]
|
||||
},
|
||||
"app": [
|
||||
"uninstall",
|
||||
"viewFile",
|
||||
"editFile",
|
||||
"openUrl",
|
||||
"launchPackage",
|
||||
"launch",
|
||||
"launchApp",
|
||||
"getPackageName",
|
||||
"openAppSetting"
|
||||
],
|
||||
"automator": [
|
||||
"click",
|
||||
"longClick",
|
||||
"press",
|
||||
"swipe",
|
||||
"gesture",
|
||||
"gestures",
|
||||
"gestureAsync",
|
||||
"gesturesAsync",
|
||||
"scrollDown",
|
||||
"scrollUp",
|
||||
"input",
|
||||
"setText"
|
||||
],
|
||||
"console": [
|
||||
"show",
|
||||
"hide",
|
||||
"clear",
|
||||
"verbose",
|
||||
"print",
|
||||
"info",
|
||||
"log",
|
||||
"warn",
|
||||
"error",
|
||||
"assert"
|
||||
],
|
||||
"dialogs":[
|
||||
"select",
|
||||
"singleChoice",
|
||||
"multiChoice",
|
||||
"rawInput",
|
||||
"input",
|
||||
"alert",
|
||||
"confirm",
|
||||
"prompt"
|
||||
],
|
||||
"images": [
|
||||
"saveImage",
|
||||
"pixel",
|
||||
"read",
|
||||
"requestScreenCapture",
|
||||
"captureScreen",
|
||||
"findColor",
|
||||
"findColorInRegion",
|
||||
"findColorEquals"
|
||||
],
|
||||
"colors": [
|
||||
"red",
|
||||
"green",
|
||||
"blue",
|
||||
"alpha",
|
||||
"toString",
|
||||
"rgb",
|
||||
"argb"
|
||||
],
|
||||
"events": [
|
||||
"emitter",
|
||||
"observeKey",
|
||||
"observeTouch",
|
||||
"onKeyDown",
|
||||
"onKeyUp",
|
||||
"onceKeyDown",
|
||||
"onceKeyUp",
|
||||
"removeAllKeyDownListeners",
|
||||
"removeAllKeyUpListeners",
|
||||
"onTouch",
|
||||
"removeAllTouchListeners",
|
||||
"getTouchEventTimeout",
|
||||
"setTouchEventTimeout",
|
||||
"on",
|
||||
"once",
|
||||
"emit",
|
||||
"getListeners",
|
||||
"addListener",
|
||||
"eventNames",
|
||||
"listenerCount",
|
||||
"listeners",
|
||||
"prependListener",
|
||||
"prependOnceListener",
|
||||
"removeAllListeners",
|
||||
"removeAllListeners",
|
||||
"removeListener",
|
||||
"setMaxListeners",
|
||||
"getMaxListeners",
|
||||
"defaultMaxListeners"
|
||||
],
|
||||
"files": [
|
||||
"open",
|
||||
"isFile",
|
||||
"isDir",
|
||||
"isEmptyDir",
|
||||
"join",
|
||||
"create",
|
||||
"createIfNotExists",
|
||||
"exists",
|
||||
"ensureDir",
|
||||
"read",
|
||||
"write",
|
||||
"copy",
|
||||
"rename",
|
||||
"renameWithoutExtension",
|
||||
"getName",
|
||||
"getExtension",
|
||||
"remove",
|
||||
"removeDir",
|
||||
"getSdcardPath",
|
||||
"listDir"
|
||||
],
|
||||
"timers": [
|
||||
"loop",
|
||||
"setTimeout",
|
||||
"clearTimeout",
|
||||
"setInterval",
|
||||
"clearInterval",
|
||||
"setImmediate",
|
||||
"clearImmediate"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import com.stardust.autojs.runtime.api.AutomatorConfig;
|
||||
import com.stardust.automator.AccessibilityEventCommandHost;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
|
||||
import org.mozilla.javascript.NativeArray;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -143,8 +145,6 @@ public class Pref {
|
||||
}
|
||||
def().edit().putLong(KEY_LAST_SHOW_AD_MILLIS, System.currentTimeMillis()).apply();
|
||||
return true;
|
||||
case "Off":
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.stardust.scriptdroid.tool;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/21.
|
||||
*/
|
||||
|
||||
public class GsonUtils {
|
||||
|
||||
public static List<String> toReservedStringList(JsonElement element) {
|
||||
JsonArray array = element.getAsJsonArray();
|
||||
List<String> list = new ArrayList<>(array.size());
|
||||
for (int i = array.size() - 1; i >= 0; i--) {
|
||||
list.add(array.get(i).getAsString());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<String> toStringList(JsonElement element) {
|
||||
JsonArray array = element.getAsJsonArray();
|
||||
List<String> list = new ArrayList<>(array.size());
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
list.add(array.get(i).getAsString());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,20 @@
|
||||
package com.stardust.scriptdroid.ui.edit.completion;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
import com.jecelyin.editor.v2.core.widget.TextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@@ -48,19 +46,26 @@ public class CodeCompletion implements TextWatcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(CodeCompletionItem o) {
|
||||
public int compareTo(@NonNull CodeCompletionItem o) {
|
||||
return mDisplayText.compareTo(o.mDisplayText);
|
||||
}
|
||||
}
|
||||
|
||||
interface OnCodeCompletionChangeListener {
|
||||
void OnCodeCompletionChange(Collection<CodeCompletionItem>... list);
|
||||
void OnCodeCompletionChange(@NonNull Collection<CodeCompletionItem> list1, @NonNull Collection<CodeCompletionItem> list2);
|
||||
}
|
||||
|
||||
private static final String TAG = "CodeCompletion";
|
||||
|
||||
private OnCodeCompletionChangeListener mOnCodeCompletionChangeListener;
|
||||
private TextView mEditText;
|
||||
private static final List<String> KEYWORDS = Arrays.asList("arguments", "break", "case", "catch", "class", "continue", "default", "do", "else", "eval", "export", "false", "for", "function", "if", "import", "in", "int", "new", "null", "package", "return", "switch", "this", "throw", "throws", "true", "try", "typeof", "var", "volatile", "while", "with", "Array", "Date", "hasOwnProperty", "Infinity", "isFinite", "isNaN", "isPrototypeOf", "length", "Math", "NaN", "name", "Number", "Object", "prototype", "String", "toString", "undefined", "valueOf");
|
||||
private static final int KEY_WORD_LENGTH_MAX = 15;
|
||||
|
||||
|
||||
private List<String> mGlobal = Collections.emptyList();
|
||||
private Map<String, List<String>> mVariableProperties = new HashMap<>();
|
||||
|
||||
|
||||
public CodeCompletion(OnCodeCompletionChangeListener listener) {
|
||||
mOnCodeCompletionChangeListener = listener;
|
||||
@@ -71,6 +76,14 @@ public class CodeCompletion implements TextWatcher {
|
||||
mEditText.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
public void setGlobal(List<String> functions) {
|
||||
mGlobal = functions;
|
||||
}
|
||||
|
||||
public void setVariableProperties(Map<String, List<String>> variableProperties) {
|
||||
mVariableProperties = variableProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
@@ -82,60 +95,94 @@ public class CodeCompletion implements TextWatcher {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
int position = mEditText.getSelectionStart();
|
||||
String str = parseWordBefore(s, position);
|
||||
if (!TextUtils.isEmpty(str))
|
||||
searchCodeCompletion(str);
|
||||
else
|
||||
mOnCodeCompletionChangeListener.OnCodeCompletionChange(DEFAULT_CODE_COMPLETION_LIST);
|
||||
|
||||
String[] str = parseWordBefore(s, position);
|
||||
if (str != null) {
|
||||
if (str[1] != null) {
|
||||
searchCodeCompletionForVariable(str[0], str[1]);
|
||||
} else {
|
||||
searchCodeCompletionForGlobal(str[0]);
|
||||
}
|
||||
} else {
|
||||
mOnCodeCompletionChangeListener.OnCodeCompletionChange(DEFAULT_CODE_COMPLETION_LIST, Collections.<CodeCompletionItem>emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
private String parseWordBefore(Editable s, int position) {
|
||||
private String[] parseWordBefore(Editable s, int position) {
|
||||
int i;
|
||||
for (i = position - 1; i >= 0; i--) {
|
||||
if (position - i > KEY_WORD_LENGTH_MAX) {
|
||||
return null;
|
||||
}
|
||||
char c = s.charAt(i);
|
||||
if (c == '.') {
|
||||
return new String[]{parseWordBeforeDot(s, i), s.subSequence(i + 1, position).toString()};
|
||||
}
|
||||
if (!Character.isLetter(s.charAt(i))) {
|
||||
if (i < position - 1) {
|
||||
return new String[]{s.subSequence(i + 1, position).toString(), null};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String parseWordBeforeDot(Editable s, int position) {
|
||||
int i;
|
||||
for (i = position - 1; i >= 0; i--) {
|
||||
if (position - i > KEY_WORD_LENGTH_MAX) {
|
||||
return null;
|
||||
}
|
||||
if (!Character.isLetter(s.charAt(i))) {
|
||||
break;
|
||||
if (i < position - 1) {
|
||||
return s.subSequence(i + 1, position).toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i < position - 1) {
|
||||
return s.subSequence(i + 1, position).toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static final String[] KEYWORDS = {"arguments", "break", "case", "catch", "class", "continue", "default", "do", "else", "eval", "export", "false", "for", "function", "if", "import", "in", "int", "new", "null", "package", "return", "switch", "this", "throw", "throws", "true", "try", "typeof", "var", "volatile", "while", "with", "Array", "Date", "hasOwnProperty", "Infinity", "isFinite", "isNaN", "isPrototypeOf", "length", "Math", "NaN", "name", "Number", "Object", "prototype", "String", "toString", "undefined", "valueOf"};
|
||||
private static final int KEY_WORD_LENGTH_MAX = 15;
|
||||
|
||||
public void setFunctions(String[] functions) {
|
||||
mFunctions = functions;
|
||||
}
|
||||
|
||||
private String[] mFunctions = new String[0];
|
||||
|
||||
private boolean searchCodeCompletion(String str) {
|
||||
private boolean searchCodeCompletionForGlobal(String str) {
|
||||
Collection<CodeCompletionItem> c = searchWordCompletion(str);
|
||||
c.addAll(searchCodeCompletion(str, mFunctions));
|
||||
c.addAll(searchCodeCompletion(str, mGlobal));
|
||||
c.addAll(searchKeyWordCompletion(str));
|
||||
if (c.size() > 0) {
|
||||
mOnCodeCompletionChangeListener.OnCodeCompletionChange(c, DEFAULT_CODE_COMPLETION_LIST);
|
||||
return true;
|
||||
} else {
|
||||
mOnCodeCompletionChangeListener.OnCodeCompletionChange(DEFAULT_CODE_COMPLETION_LIST);
|
||||
mOnCodeCompletionChangeListener.OnCodeCompletionChange(DEFAULT_CODE_COMPLETION_LIST, Collections.<CodeCompletionItem>emptyList());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean searchCodeCompletionForVariable(String variable, String str) {
|
||||
List<String> properties = getPropertiesForVariable(variable);
|
||||
Collection<CodeCompletionItem> c = searchCodeCompletion(str, properties);
|
||||
mOnCodeCompletionChangeListener.OnCodeCompletionChange(c, Collections.<CodeCompletionItem>emptyList());
|
||||
return !c.isEmpty();
|
||||
}
|
||||
|
||||
private List<String> getPropertiesForVariable(String str) {
|
||||
List<String> properties = mVariableProperties.get(str);
|
||||
if (properties == null)
|
||||
return Collections.emptyList();
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
private Collection<CodeCompletionItem> searchWordCompletion(String str) {
|
||||
if (mEditText.getEditableText().length() < Pref.getMaxTextLengthForCodeCompletion()) {
|
||||
return searchCodeCompletion(str, splitWord(mEditText.getEditableText().toString()));
|
||||
return searchCodeCompletion(str, Arrays.asList(splitWord(mEditText.getEditableText().toString())));
|
||||
}
|
||||
return new TreeSet<>();
|
||||
}
|
||||
|
||||
private Collection<CodeCompletionItem> searchCodeCompletion(String str, String[] words) {
|
||||
private Collection<CodeCompletionItem> searchCodeCompletion(String str, Iterable<String> words) {
|
||||
Set<CodeCompletionItem> set = new TreeSet<>();
|
||||
for (String word : words) {
|
||||
// TODO: 2017/2/18 优化 字典树
|
||||
|
||||
@@ -3,8 +3,8 @@ package com.stardust.scriptdroid.ui.edit.completion;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -15,21 +15,27 @@ import android.widget.Toast;
|
||||
import android.workground.WrapContentLinearLayoutManager;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.tool.GsonUtils;
|
||||
import com.stardust.util.UnderuseExecutors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/17.
|
||||
*/
|
||||
|
||||
// TODO: 2017/7/21 refactor
|
||||
public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletion.OnCodeCompletionChangeListener {
|
||||
|
||||
|
||||
@@ -48,6 +54,14 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnCodeCompletionChange(@NonNull Collection<CodeCompletion.CodeCompletionItem> list1, @NonNull Collection<CodeCompletion.CodeCompletionItem> list2) {
|
||||
mCodeCompletionList.clear();
|
||||
mCodeCompletionList.addAll(list1);
|
||||
mCodeCompletionList.addAll(list2);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public interface EditTextBridge {
|
||||
void appendText(CharSequence text);
|
||||
|
||||
@@ -56,6 +70,9 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
|
||||
com.jecelyin.editor.v2.core.widget.TextView getEditText();
|
||||
}
|
||||
|
||||
private static List<String> global;
|
||||
private static Map<String, List<String>> variables = new HashMap<>();
|
||||
|
||||
EditTextBridge mEditTextBridge;
|
||||
private CodeCompletion mCodeCompletion = new CodeCompletion(this);
|
||||
private List<CodeCompletion.CodeCompletionItem> mCodeCompletionList = new ArrayList<>();
|
||||
@@ -83,7 +100,16 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
|
||||
private void init() {
|
||||
setAdapter(new CodeCompletionAdapter());
|
||||
setLayoutManager(new WrapContentLinearLayoutManager(getContext(), HORIZONTAL, false));
|
||||
mCodeCompletion.setFunctions(readFunctions(getContext(), "js/functions.json"));
|
||||
if (global == null) {
|
||||
UnderuseExecutors.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
readCompletions(getContext(), "js/functions.json");
|
||||
mCodeCompletion.setGlobal(global);
|
||||
mCodeCompletion.setVariableProperties(variables);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void setEditTextBridge(EditTextBridge editTextBridge) {
|
||||
@@ -91,16 +117,6 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
|
||||
mCodeCompletion.setEditText(mEditTextBridge.getEditText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnCodeCompletionChange(Collection<CodeCompletion.CodeCompletionItem>... lists) {
|
||||
mCodeCompletionList.clear();
|
||||
for (Collection<CodeCompletion.CodeCompletionItem> list : lists) {
|
||||
mCodeCompletionList.addAll(list);
|
||||
}
|
||||
getAdapter().notifyDataSetChanged();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class CodeCompletionAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
@@ -129,13 +145,29 @@ public class InputMethodEnhanceBar extends RecyclerView implements CodeCompletio
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] readFunctions(Context context, String path) {
|
||||
Gson gson = new Gson();
|
||||
private static void readCompletions(Context context, String path) {
|
||||
try {
|
||||
return gson.fromJson(new InputStreamReader(context.getAssets().open(path)), String[].class);
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject object = parser.parse(new InputStreamReader(context.getAssets().open(path))).getAsJsonObject();
|
||||
InputMethodEnhanceBar.global = readGlobal(object.remove("global").getAsJsonObject());
|
||||
readModules(object);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void readModules(JsonObject object) {
|
||||
for (Map.Entry<String, JsonElement> module : object.entrySet()) {
|
||||
variables.put(module.getKey(), GsonUtils.toStringList(module.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> readGlobal(JsonObject global) {
|
||||
List<String> globalFunctions = new ArrayList<>();
|
||||
for (Map.Entry<String, JsonElement> moduleGlobal : global.entrySet()) {
|
||||
globalFunctions.addAll(GsonUtils.toStringList(moduleGlobal.getValue()));
|
||||
}
|
||||
return globalFunctions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -228,13 +228,11 @@
|
||||
<string-array name="ad_showing_mode_keys">
|
||||
<item>默认</item>
|
||||
<item>每天显示一次</item>
|
||||
<item>关闭广告</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="ad_showing_mode_values">
|
||||
<item>Default</item>
|
||||
<item>OncePerDay</item>
|
||||
<item>Off</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.stardust.automator.filter.DfsFilter;
|
||||
import com.stardust.util.DeveloperUtils;
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
|
||||
import org.mozilla.javascript.NativeArray;
|
||||
|
||||
import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
|
||||
import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT;
|
||||
import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE;
|
||||
@@ -58,21 +60,6 @@ import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.
|
||||
|
||||
public class UiSelector extends UiGlobalSelector {
|
||||
|
||||
@Deprecated
|
||||
private class FindCommand extends AccessibilityEventCommandHost.AbstractCommand {
|
||||
|
||||
UiObjectCollection result;
|
||||
|
||||
@Override
|
||||
public void execute(AccessibilityService service, AccessibilityEvent event) {
|
||||
AccessibilityNodeInfo root = service.getRootInActiveWindow();
|
||||
if (root != null) {
|
||||
result = findOf(UiObject.createRoot(root, mAllocator));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final String TAG = "UiSelector";
|
||||
|
||||
private AccessibilityBridge mAccessibilityBridge;
|
||||
|
||||
@@ -238,4 +238,5 @@ public class UiObjectCollection {
|
||||
public boolean nonEmpty() {
|
||||
return size() != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ public class PFile {
|
||||
return new File(path).isDirectory();
|
||||
}
|
||||
|
||||
public static boolean isDirEmpty(String path) {
|
||||
public static boolean isEmptyDir(String path) {
|
||||
File file = new File(path);
|
||||
return file.isDirectory() && file.list().length == 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user