add: refactor, jumping for editor
This commit is contained in:
338
app/src/main/assets/editor/codemirror/addon/autojs/autojs-global-scope.js
vendored
Normal file
338
app/src/main/assets/editor/codemirror/addon/autojs/autojs-global-scope.js
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
function autoJsGlobalScope(){
|
||||
var globals = {
|
||||
"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"
|
||||
]
|
||||
};
|
||||
var modules = {
|
||||
"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",
|
||||
"observeNotification",
|
||||
"onKeyDown",
|
||||
"onKeyUp",
|
||||
"onceKeyDown",
|
||||
"onceKeyUp",
|
||||
"onToast",
|
||||
"onNotification",
|
||||
"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"
|
||||
]
|
||||
};
|
||||
function for_each(obj, func){
|
||||
for(var key in obj){
|
||||
if(!obj.hasOwnProperty(key)){
|
||||
continue;
|
||||
}
|
||||
func(key, obj[key]);
|
||||
}
|
||||
}
|
||||
var __global__ = {};
|
||||
for_each(modules, function(moduleName, moduleVariables){
|
||||
if(!__global__[moduleName]){
|
||||
__global__[moduleName] = {};
|
||||
}
|
||||
for(var i = 0; i < moduleVariables.length; i++){
|
||||
if(!__global__[moduleName][moduleVariables[i]]){
|
||||
__global__[moduleName][moduleVariables[i]] = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
for_each(globals, function(moduleName, moduleVariables){
|
||||
for(var i = 0; i < moduleVariables.length; i++){
|
||||
if(!__global__[moduleVariables[i]]){
|
||||
__global__[moduleVariables[i]] = '';
|
||||
}
|
||||
}
|
||||
})
|
||||
return __global__;
|
||||
}
|
||||
|
||||
@@ -1,338 +1,61 @@
|
||||
function autoJsGlobalScope(){
|
||||
var globals = {
|
||||
"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"
|
||||
]
|
||||
};
|
||||
var modules = {
|
||||
"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",
|
||||
"observeNotification",
|
||||
"onKeyDown",
|
||||
"onKeyUp",
|
||||
"onceKeyDown",
|
||||
"onceKeyUp",
|
||||
"onToast",
|
||||
"onNotification",
|
||||
"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"
|
||||
]
|
||||
};
|
||||
function for_each(obj, func){
|
||||
for(var key in obj){
|
||||
if(!obj.hasOwnProperty(key)){
|
||||
continue;
|
||||
}
|
||||
func(key, obj[key]);
|
||||
function autojs(editor){
|
||||
function loadJs(url){
|
||||
var script = document.createElement("script");
|
||||
// This script has a callback function that will run when the script has
|
||||
// finished loading.
|
||||
script.src = url;
|
||||
script.type = "text/javascript";
|
||||
document.getElementsByTagName("head")[0].appendChild(script);
|
||||
}
|
||||
var server = null;
|
||||
var getURL = function(url, c) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("get", url, true);
|
||||
xhr.send();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState != 4) return;
|
||||
if (xhr.status < 400) return c(null, xhr.responseText);
|
||||
var e = new Error(xhr.responseText || "No response");
|
||||
e.status = xhr.status;
|
||||
c(e);
|
||||
};
|
||||
}
|
||||
connect();
|
||||
editor.tern = {};
|
||||
editor.tern.showType = function(){
|
||||
checkServer();
|
||||
server.showType(editor);
|
||||
}
|
||||
editor.tern.jumpToDef = function(){
|
||||
checkServer();
|
||||
server.jumpToDef(editor);
|
||||
}
|
||||
editor.tern.rename = function(){
|
||||
checkServer();
|
||||
server.rename(editor);
|
||||
}
|
||||
editor.tern.selectName = function(){
|
||||
checkServer();
|
||||
server.selectName(editor);
|
||||
}
|
||||
editor.tern.jumpBack = function(){
|
||||
checkServer();
|
||||
server.jumpBack(editor);
|
||||
}
|
||||
|
||||
function connect(){
|
||||
getURL("http://ternjs.net/defs/ecmascript.json", function(err, code) {
|
||||
if (err) throw new Error("Request for ecmascript.json: " + err);
|
||||
server = new CodeMirror.TernServer({defs: [JSON.parse(code)]});
|
||||
editor.tern.server = server;
|
||||
editor.on("cursorActivity", function(cm) { server.updateArgHints(cm); });
|
||||
});
|
||||
}
|
||||
|
||||
function checkServer(){
|
||||
if(!server){
|
||||
alert("Error: cannot connect to tern server\n联网获取编辑器增强服务失败:(\n");
|
||||
connect();
|
||||
}
|
||||
}
|
||||
var __global__ = {};
|
||||
for_each(modules, function(moduleName, moduleVariables){
|
||||
if(!__global__[moduleName]){
|
||||
__global__[moduleName] = {};
|
||||
}
|
||||
for(var i = 0; i < moduleVariables.length; i++){
|
||||
if(!__global__[moduleName][moduleVariables[i]]){
|
||||
__global__[moduleName][moduleVariables[i]] = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
for_each(globals, function(moduleName, moduleVariables){
|
||||
for(var i = 0; i < moduleVariables.length; i++){
|
||||
if(!__global__[moduleVariables[i]]){
|
||||
__global__[moduleVariables[i]] = '';
|
||||
}
|
||||
}
|
||||
})
|
||||
return __global__;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,6 +42,7 @@
|
||||
<script type="text/javascript" src="codemirror/addon/search/searchcursor.js"></script>
|
||||
|
||||
<!-- Auto.js -->
|
||||
<script type="text/javascript" src="codemirror/addon/autojs/autojs-global-scope.js"></script>
|
||||
<script type="text/javascript" src="codemirror/addon/autojs/autojs.js"></script>
|
||||
|
||||
<head>
|
||||
@@ -50,26 +51,20 @@
|
||||
<body>
|
||||
<textarea id="code"></textarea>
|
||||
</body>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true, // 显示行数
|
||||
indentUnit: 4, // 缩进单位为4
|
||||
styleActiveLine: true, // 当前行背景高亮
|
||||
foldGutter: true,
|
||||
gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
matchBrackets: true, // 括号匹配
|
||||
mode: 'javascript', // HMTL混合模式
|
||||
lineWrapping: false, // 自动换行
|
||||
theme: 'neo' // 使用neo模版
|
||||
});
|
||||
editor.setOption("fullScreen", true);
|
||||
editor.setOption("hintOptions", {
|
||||
completeSingle: false,
|
||||
globalScope: autoJsGlobalScope()
|
||||
});
|
||||
editor.on("keyup", function(cm, e) {
|
||||
editor.execCommand("autocomplete")
|
||||
})
|
||||
editor.setCursor({line: 0, ch: 0});
|
||||
</script>
|
||||
|
||||
<!-- Tern -->
|
||||
<script src="codemirror/addon/tern/tern.js"></script>
|
||||
<link rel="stylesheet" href="codemirror/addon/tern/tern.css">
|
||||
<script src="http://ternjs.net/node_modules/acorn/dist/acorn.js"></script>
|
||||
<script src="http://ternjs.net/node_modules/acorn/dist/acorn_loose.js"></script>
|
||||
<script src="http://ternjs.net/node_modules/acorn/dist/walk.js"></script>
|
||||
<script src="http://ternjs.net/doc/demo/polyfill.js"></script>
|
||||
<script src="http://ternjs.net/lib/signal.js"></script>
|
||||
<script src="http://ternjs.net/lib/tern.js"></script>
|
||||
<script src="http://ternjs.net/lib/def.js"></script>
|
||||
<script src="http://ternjs.net/lib/comment.js"></script>
|
||||
<script src="http://ternjs.net/lib/infer.js"></script>
|
||||
<script src="http://ternjs.net/plugin/doc_comment.js"></script>
|
||||
|
||||
<script src="index.js"></script>
|
||||
</html>
|
||||
24
app/src/main/assets/editor/index.js
Normal file
24
app/src/main/assets/editor/index.js
Normal file
@@ -0,0 +1,24 @@
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true, // 显示行数
|
||||
indentUnit: 4, // 缩进单位为4
|
||||
styleActiveLine: true, // 当前行背景高亮
|
||||
foldGutter: true,
|
||||
gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
matchBrackets: true, // 括号匹配
|
||||
mode: 'javascript',
|
||||
lineWrapping: false, // 自动换行
|
||||
theme: 'neo' // 使用neo主题
|
||||
});
|
||||
editor.setOption("fullScreen", true);
|
||||
editor.setOption("hintOptions", {
|
||||
completeSingle: false,
|
||||
globalScope: autoJsGlobalScope()
|
||||
});
|
||||
editor.on("keyup", function(cm, e) {
|
||||
editor.execCommand("autocomplete");
|
||||
})
|
||||
editor.setCursor({line: 0, ch: 0});
|
||||
|
||||
window.onload = function(){
|
||||
autojs(editor);
|
||||
}
|
||||
@@ -1,19 +1,26 @@
|
||||
package com.stardust.scriptdroid.ui.edit;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.JsPromptResult;
|
||||
import android.webkit.JsResult;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.jdeferred.Deferred;
|
||||
@@ -24,6 +31,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
@@ -32,6 +41,7 @@ import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
|
||||
import retrofit2.http.GET;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/9/27.
|
||||
@@ -41,7 +51,6 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
|
||||
private static final String LOG_TAG = "CodeMirrorEditor";
|
||||
|
||||
|
||||
public interface Callback {
|
||||
void onChange();
|
||||
|
||||
@@ -158,7 +167,7 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
settings.setNeedInitialFocus(true);
|
||||
settings.setDisplayZoomControls(false);
|
||||
mWebView.setWebViewClient(new MyWebViewClient());
|
||||
mWebView.setWebChromeClient(new WebChromeClient());
|
||||
mWebView.setWebChromeClient(new MyWebChromeClient());
|
||||
}
|
||||
|
||||
public void setProgress(boolean onProgress) {
|
||||
@@ -268,6 +277,41 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
evalJavaScript("editor.execCommand('replaceAll');");
|
||||
}
|
||||
|
||||
public void jumpToDef() {
|
||||
evalJavaScript("editor.tern.jumpToDef();");
|
||||
}
|
||||
|
||||
|
||||
public void jumpToLineStart() {
|
||||
evalJavaScript("editor.execCommand('goLineStart');");
|
||||
}
|
||||
|
||||
public void jumpToLineEnd() {
|
||||
evalJavaScript("editor.execCommand('goLineEnd')");
|
||||
}
|
||||
|
||||
public void jumpToStart() {
|
||||
evalJavaScript("editor.execCommand('goDocStart');");
|
||||
}
|
||||
|
||||
public void jumpToEnd() {
|
||||
evalJavaScript("editor.execCommand('goDocEnd');");
|
||||
}
|
||||
|
||||
|
||||
public void showType() {
|
||||
evalJavaScript("editor.tern.showType();");
|
||||
}
|
||||
|
||||
public void rename() {
|
||||
evalJavaScript("editor.tern.rename();");
|
||||
}
|
||||
|
||||
public void selectName() {
|
||||
evalJavaScript("editor.tern.selectName();");
|
||||
}
|
||||
|
||||
|
||||
public void replace(String keywords, String replacement, boolean usingRegex) {
|
||||
setQuery(keywords, usingRegex);
|
||||
replacement = replacement.replace("'", "\'");
|
||||
@@ -275,6 +319,12 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
findNext();
|
||||
}
|
||||
|
||||
public Observable<String> getSelection() {
|
||||
mStringFromJs = PublishSubject.create();
|
||||
evalJavaScript("__bridge__.setStringFromJs(editor.getSelection());");
|
||||
return mStringFromJs;
|
||||
}
|
||||
|
||||
public void replaceSelection() {
|
||||
evalJavaScript("editor.execCommand('replace');");
|
||||
}
|
||||
@@ -355,7 +405,61 @@ public class CodeMirrorEditor extends FrameLayout {
|
||||
mPageFinished.resolve(null);
|
||||
evalJavaScript(INIT_SCRIPT);
|
||||
setProgress(false);
|
||||
// evalJavaScript("editor.setSize(" + mWebView.getMeasuredWidth() + ", " + mWebView.getMeasuredHeight() + ");");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MyWebChromeClient extends WebChromeClient {
|
||||
|
||||
private final Pattern RENAME = Pattern.compile("New name for ([a-zA-Z]+)");
|
||||
|
||||
@Override
|
||||
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
|
||||
Matcher m = RENAME.matcher(message);
|
||||
if (m.matches() && m.groupCount() >= 1) {
|
||||
showRenamePrompt(m.group(1), defaultValue, result);
|
||||
return true;
|
||||
}
|
||||
return super.onJsPrompt(view, url, message, defaultValue, result);
|
||||
}
|
||||
|
||||
private void showRenamePrompt(String name, String defaultValue, final JsPromptResult result) {
|
||||
new ThemeColorMaterialDialogBuilder(getContext())
|
||||
.title(getResources().getString(R.string.text_rename) + name)
|
||||
.input("", defaultValue, new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@android.support.annotation.NonNull MaterialDialog dialog, CharSequence input) {
|
||||
result.confirm(input.toString());
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
|
||||
new ThemeColorMaterialDialogBuilder(getContext())
|
||||
.title(R.string.text_alert)
|
||||
.content(message)
|
||||
.onPositive(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@android.support.annotation.NonNull MaterialDialog dialog, @android.support.annotation.NonNull DialogAction which) {
|
||||
result.confirm();
|
||||
}
|
||||
})
|
||||
.cancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
result.cancel();
|
||||
}
|
||||
})
|
||||
.positiveText(R.string.ok)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
mProgressBar.setVisibility(newProgress == 100 ? VISIBLE : GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,22 +38,22 @@ public class EditorMenu {
|
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_console:
|
||||
showConsole();
|
||||
return true;
|
||||
case R.id.action_log:
|
||||
showLog();
|
||||
return true;
|
||||
case R.id.action_force_stop:
|
||||
forceStop();
|
||||
return true;
|
||||
case R.id.action_jump:
|
||||
jump();
|
||||
return true;
|
||||
default:
|
||||
if (onEditOptionsSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
if (onRefactorOptionsSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
if (onJumpOptionsSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
if (onMoreOptionsSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
@@ -61,12 +61,54 @@ public class EditorMenu {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onJumpOptionsSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_jump_to_line:
|
||||
jumpToLine();
|
||||
return true;
|
||||
case R.id.action_jump_to_def:
|
||||
mEditor.jumpToDef();
|
||||
return true;
|
||||
case R.id.action_jump_to_start:
|
||||
mEditor.jumpToStart();
|
||||
return true;
|
||||
case R.id.action_jump_to_end:
|
||||
mEditor.jumpToEnd();
|
||||
return true;
|
||||
case R.id.action_jump_to_line_start:
|
||||
mEditor.jumpToLineStart();
|
||||
return true;
|
||||
case R.id.action_jump_to_line_end:
|
||||
mEditor.jumpToLineEnd();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onMoreOptionsSelected(MenuItem item) {
|
||||
private boolean onRefactorOptionsSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_beautify:
|
||||
beautifyCode();
|
||||
return true;
|
||||
case R.id.action_rename:
|
||||
mEditor.rename();
|
||||
return true;
|
||||
case R.id.action_select_variable:
|
||||
mEditor.selectName();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean onMoreOptionsSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_console:
|
||||
showConsole();
|
||||
return true;
|
||||
case R.id.action_show_type:
|
||||
mEditor.showType();
|
||||
return true;
|
||||
case R.id.action_editor_theme:
|
||||
mEditorView.selectEditorTheme();
|
||||
return true;
|
||||
@@ -106,7 +148,7 @@ public class EditorMenu {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void jump() {
|
||||
private void jumpToLine() {
|
||||
mEditor.getLineCount()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<Integer>() {
|
||||
@@ -180,8 +222,17 @@ public class EditorMenu {
|
||||
}
|
||||
|
||||
private void findOrReplace() {
|
||||
new FindOrReplaceDialogBuilder(mContext, mEditorView)
|
||||
.show();
|
||||
mEditor.getSelection()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Consumer<String>() {
|
||||
@Override
|
||||
public void accept(@NonNull String s) throws Exception {
|
||||
new FindOrReplaceDialogBuilder(mContext, mEditorView)
|
||||
.setQueryIfNotEmpty(s)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void copyAll() {
|
||||
|
||||
@@ -120,4 +120,10 @@ public class FindOrReplaceDialogBuilder extends ThemeColorMaterialDialogBuilder
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public FindOrReplaceDialogBuilder setQueryIfNotEmpty(String s) {
|
||||
if (!TextUtils.isEmpty(s))
|
||||
mKeywordsEditText.setText(s);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,15 +46,64 @@
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump"
|
||||
android:title="@string/text_jump_to_line"
|
||||
app:showAsAction="never"/>
|
||||
android:title="@string/text_jump"
|
||||
app:showAsAction="never">
|
||||
|
||||
<menu>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump_to_def"
|
||||
android:title="@string/text_jump_to_def"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump_to_line"
|
||||
android:title="@string/text_jump_to_line"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump_to_start"
|
||||
android:title="@string/text_jump_to_start"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump_to_end"
|
||||
android:title="@string/text_jump_to_end"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump_to_line_start"
|
||||
android:title="@string/text_jump_to_line_start"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_jump_to_line_end"
|
||||
android:title="@string/text_jump_to_line_end"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
|
||||
</item>
|
||||
|
||||
|
||||
<item
|
||||
android:id="@+id/action_console"
|
||||
android:title="@string/text_console"
|
||||
app:showAsAction="never"/>
|
||||
<item android:title="@string/text_refactor">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/action_rename"
|
||||
android:title="@string/text_rename"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_select_variable"
|
||||
android:title="@string/text_select_variable"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_beautify"
|
||||
android:title="@string/text_code_beautify"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_log"
|
||||
@@ -63,10 +112,14 @@
|
||||
|
||||
<item android:title="@string/text_more">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/action_console"
|
||||
android:title="@string/text_console"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_beautify"
|
||||
android:title="@string/text_code_beautify"
|
||||
android:id="@+id/action_show_type"
|
||||
android:title="@string/text_show_type"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
|
||||
@@ -269,7 +269,16 @@
|
||||
<string name="text_replace_all">全部替换</string>
|
||||
<string name="text_find_next">向下</string>
|
||||
<string name="text_find_prev">向上</string>
|
||||
<string name="hint_regex">正则语法与JavaScript中相同, 可使用$1-9代替被捕获的匹配</string>
|
||||
<string name="hint_regex">正则语法与JavaScript中相同, 可使用$1~9代替被捕获的匹配</string>
|
||||
<string name="text_jump">跳转</string>
|
||||
<string name="text_jump_to_def">转到定义</string>
|
||||
<string name="text_jump_to_end">转到文件末尾</string>
|
||||
<string name="text_jump_to_start">转到文件开始</string>
|
||||
<string name="text_jump_to_line_start">转到行首</string>
|
||||
<string name="text_jump_to_line_end">转到行尾</string>
|
||||
<string name="text_refactor">重构</string>
|
||||
<string name="text_select_variable">选择变量</string>
|
||||
<string name="text_show_type">显示变量类型</string>
|
||||
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
|
||||
Reference in New Issue
Block a user