From 91a1cb77d824a02fec2ef54afa98afc59bb5cda6 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Mon, 15 May 2017 19:47:58 +0800 Subject: [PATCH] add multi-line string support --- app/src/main/assets/sample/界面/登录界面.js | 58 +++++++++++ autojs/src/main/assets/modules/__ui__.js | 21 +++- .../autojs/engine/MultiLinePreprocessor.java | 99 +++++++++++++++++++ .../autojs/engine/RhinoJavaScriptEngine.java | 22 ++--- .../engine/preprocess/AbstractProcessor.java | 31 ++++++ .../engine/preprocess/Preprocessor.java | 13 +++ .../execution/ScriptExecuteActivity.java | 2 + .../stardust/autojs/runtime/api/AppUtils.java | 7 +- .../engine/MultiLinePreprocessorTest.java | 77 +++++++++++++++ 9 files changed, 312 insertions(+), 18 deletions(-) create mode 100644 app/src/main/assets/sample/界面/登录界面.js create mode 100644 autojs/src/main/java/com/stardust/autojs/engine/MultiLinePreprocessor.java create mode 100644 autojs/src/main/java/com/stardust/autojs/engine/preprocess/AbstractProcessor.java create mode 100644 autojs/src/main/java/com/stardust/autojs/engine/preprocess/Preprocessor.java create mode 100644 autojs/src/test/java/com/stardust/autojs/engine/MultiLinePreprocessorTest.java diff --git a/app/src/main/assets/sample/界面/登录界面.js b/app/src/main/assets/sample/界面/登录界面.js new file mode 100644 index 00000000..7b36b181 --- /dev/null +++ b/app/src/main/assets/sample/界面/登录界面.js @@ -0,0 +1,58 @@ +"ui"; + +ui.statusBarColor("#000000") +showLoginUI(); + +//显示登录界面 +function showLoginUI(){ + ui.layout(` + + + + 用户名 + + + + 密码 + + + + + + + + + `); + ui.cancel.click(() => showLoginUI()); +} \ No newline at end of file diff --git a/autojs/src/main/assets/modules/__ui__.js b/autojs/src/main/assets/modules/__ui__.js index 4de71eb2..fb274637 100644 --- a/autojs/src/main/assets/modules/__ui__.js +++ b/autojs/src/main/assets/modules/__ui__.js @@ -1,5 +1,6 @@ module.exports = function(__runtime__, scope){ var ui = Object(__runtime__.ui); + ui.__id_cache__ = {}; ui.layout = function(xml){ view = ui.inflate(activity, xml); @@ -8,6 +9,7 @@ module.exports = function(__runtime__, scope){ ui.setContentView = function(view){ ui.view = view; + ui.__id_cache__ = {}; activity.setContentView(view); } @@ -31,6 +33,13 @@ module.exports = function(__runtime__, scope){ __runtime__.getUiHandler().postDelay(action, delay); } + ui.statusBarColor = function(color){ + if(typeof(color) == 'string'){ + color = android.graphics.Color.parseColor(color); + } + activity.getWindow().setStatusBarColor(color); + } + function decorate(view){ var view = Object.create(view); view._id = function(id){ @@ -59,10 +68,14 @@ module.exports = function(__runtime__, scope){ }, get: function(name, start) { if(!ui[name]){ - var widget = ui.id(name); - if(widget){ - ui[name] = widget; - return widget; + var cacheView = ui.__id_cache__[name]; + if(cacheView){ + return cacheView; + } + cacheView = ui.id(name); + if(cacheView){ + ui.__id_cache__[name] = cacheView; + return cacheView; } } return ui[name]; diff --git a/autojs/src/main/java/com/stardust/autojs/engine/MultiLinePreprocessor.java b/autojs/src/main/java/com/stardust/autojs/engine/MultiLinePreprocessor.java new file mode 100644 index 00000000..fab49337 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/engine/MultiLinePreprocessor.java @@ -0,0 +1,99 @@ +package com.stardust.autojs.engine; + +import android.support.annotation.VisibleForTesting; + +import com.stardust.autojs.engine.preprocess.AbstractProcessor; + +import java.io.Reader; +import java.io.StringReader; + +/** + * Created by Stardust on 2017/5/15. + */ + +public class MultiLinePreprocessor extends AbstractProcessor { + + private static final int STATE_SINGLE_QUOTE_LITERAL = 0x00000001; + private static final int STATE_DOUBLE_QUOTE_LITERAL = 0x00000010; + private static final int STATE_MULTI_LINE = 0x00001100; + + private int mState = 0; + private int mStateBeforeLiteral = 0; + private StringBuilder mNewScript; + private int mLastReturnCharPosition; + private int i; + + @Override + protected void handleChar(int ch) { + boolean shouldAppend = true; + switch (ch) { + case '"': + if (mState == STATE_DOUBLE_QUOTE_LITERAL) { + mState = mStateBeforeLiteral; + } else if (mState != STATE_SINGLE_QUOTE_LITERAL) { + mStateBeforeLiteral = mState; + mState = STATE_DOUBLE_QUOTE_LITERAL; + } + break; + case '\'': + if (mState == STATE_SINGLE_QUOTE_LITERAL) { + if ((mStateBeforeLiteral & STATE_MULTI_LINE) != 0) { + mNewScript.append('\\'); + } + mState = mStateBeforeLiteral; + } else if (mState != STATE_DOUBLE_QUOTE_LITERAL) { + mStateBeforeLiteral = mState; + mState = STATE_SINGLE_QUOTE_LITERAL; + if ((mStateBeforeLiteral & STATE_MULTI_LINE) != 0) { + mNewScript.append('\\'); + } + } + break; + case '`': + if (mState == 0) { + mState = STATE_MULTI_LINE; + mNewScript.append("'"); + shouldAppend = false; + } else if (mState == STATE_MULTI_LINE) { + mState = 0; + mNewScript.append("'"); + shouldAppend = false; + } + break; + case '\r': + case '\n': + if (ch == '\n' && mLastReturnCharPosition == i - 1) { + shouldAppend = false; + break; + } + if (ch == '\r') + mLastReturnCharPosition = i; + if (mState == STATE_MULTI_LINE) { + mNewScript.append("\\n'+\n'"); + shouldAppend = false; + } + break; + } + if (shouldAppend) { + mNewScript.append((char) ch); + } + i++; + } + + @Override + public void reset() { + mState = 0; + mStateBeforeLiteral = 0; + mNewScript = new StringBuilder(); + mLastReturnCharPosition = -2; + i = 0; + } + + @Override + public Reader getReaderAndClear() { + Reader reader = new StringReader(mNewScript.toString()); + mNewScript = null; + return reader; + } + +} diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java index 7b086807..a59bb8db 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java @@ -2,6 +2,7 @@ package com.stardust.autojs.engine; import android.util.Log; +import com.stardust.autojs.engine.preprocess.Preprocessor; import com.stardust.autojs.rhino_android.AndroidContextFactory; import com.stardust.autojs.rhino_android.RhinoAndroidHelper; import com.stardust.autojs.runtime.ScriptInterruptedException; @@ -10,27 +11,23 @@ import com.stardust.pio.UncheckedIOException; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextFactory; -import org.mozilla.javascript.ErrorReporter; -import org.mozilla.javascript.EvaluatorException; import org.mozilla.javascript.ImporterTopLevel; -import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.commonjs.module.RequireBuilder; import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider; -import org.mozilla.javascript.xmlimpl.XMLLibImpl; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.Reader; +import java.io.StringReader; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.xml.parsers.DocumentBuilderFactory; - /** * Created by Stardust on 2017/4/2. */ @@ -38,6 +35,7 @@ import javax.xml.parsers.DocumentBuilderFactory; public class RhinoJavaScriptEngine implements ScriptEngine { private static final String LOG_TAG = "RhinoJavaScriptEngine"; + private static final Preprocessor PREPROCESSOR = new MultiLinePreprocessor(); private static int contextCount = 0; private String[] mRequirePath = new String[0]; @@ -62,17 +60,19 @@ public class RhinoJavaScriptEngine implements ScriptEngine { @Override public Object execute(ScriptSource source) { - Reader reader = source.getScriptReader(); - if (reader == null) { - return mContext.evaluateString(mScriptable, source.getScript(), "