diff --git a/app/build.gradle b/app/build.gradle index bfb9e607..925202d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 19 targetSdkVersion 23 - versionCode 129 - versionName "2.0.10c Beta" + versionCode 130 + versionName "2.0.11 Alpha" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { diff --git a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java index 54bd1bdd..02bd0130 100644 --- a/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java +++ b/app/src/test/java/com/stardust/scriptdroid/ExampleUnitTest.java @@ -19,6 +19,8 @@ import java.io.PipedReader; import java.io.PipedWriter; import java.io.Writer; import java.nio.channels.Pipe; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -50,20 +52,10 @@ public class ExampleUnitTest { @Test public void test() { - PipedInputStream inputStream = new PipedInputStream(1024); - try { - System.setIn(inputStream); - OutputStream outputStream = new PipedOutputStream(inputStream); - outputStream.write("().attributes()[0].name()\n".getBytes()); - org.mozilla.javascript.tools.shell.Main.exec(new String[]{}); - inputStream.close(); - outputStream.close(); - } catch (IOException e) { - e.printStackTrace(); + Matcher matcher = Pattern.compile("\\S+").matcher("001 华为 6800"); + while (matcher.find()){ + System.out.println(matcher.group()); } - org.mozilla.javascript.xmlimpl.XMLLibImpl - - } @Test diff --git a/autojs/src/main/assets/modules/__ui__.js b/autojs/src/main/assets/modules/__ui__.js index cc17e0fd..6d7486b9 100644 --- a/autojs/src/main/assets/modules/__ui__.js +++ b/autojs/src/main/assets/modules/__ui__.js @@ -1,13 +1,20 @@ module.exports = function(__runtime__, scope){ var ui = Object(__runtime__.ui); + + ui.layout = function(xml){ view = ui.inflate(activity, xml); ui.setView(view); } ui.setView = function(view){ + ui.view = view; activity.setContentView(view); } + ui.id = function(id){ + return ui.view.getChildAt(0).id(id); + } + return ui; } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/AttributeHandler.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/AttributeHandler.java index 06fec3f1..12c516a5 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/AttributeHandler.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/AttributeHandler.java @@ -9,6 +9,7 @@ import org.w3c.dom.Node; import java.util.HashMap; import java.util.Map; +import java.util.regex.Matcher; /** * Created by Stardust on 2017/5/14. @@ -31,12 +32,12 @@ public interface AttributeHandler { return handler != null && handler.handle(nodeName, attr, layoutXml); } - public AttrNameRouter registerHandler(String attrName, AttributeHandler handler) { + public AttrNameRouter handler(String attrName, AttributeHandler handler) { mHandlerMap.put(attrName, handler); return this; } - public AttrNameRouter setDefaultHandler(AttributeHandler defaultHandler) { + public AttrNameRouter defaultHandler(AttributeHandler defaultHandler) { mDefaultHandler = defaultHandler; return this; } @@ -54,12 +55,12 @@ public interface AttributeHandler { return true; } - public MappedAttributeHandler putAttrNameMap(String oldAttrName, String newAttrName) { + public MappedAttributeHandler mapName(String oldAttrName, String newAttrName) { mAttrNameMap.put(oldAttrName, newAttrName); return this; } - public MappedAttributeHandler putAttrValueMap(String attrName, String oldValue, String newValue) { + public MappedAttributeHandler mapValue(String attrName, String oldValue, String newValue) { Map valueMap = mAttrValueMap.get(attrName); if (valueMap == null) { valueMap = new HashMap<>(); @@ -123,4 +124,66 @@ public interface AttributeHandler { return dimen; } } + + class OrientationHandler implements AttributeHandler { + + @Override + public boolean handle(String nodeName, Node attr, StringBuilder layoutXml) { + if (attr.getNodeValue().equals("true")) { + layoutXml.append("android:orientation=\"vertical\"\n"); + } else if (attr.getNodeValue().equals("false")) { + layoutXml.append("android:orientation=\"horizontal\"\n"); + } else { + return false; + } + return true; + } + } + + class MarginPaddingHandler implements AttributeHandler { + + private String mAttrName; + + public MarginPaddingHandler(String attrName) { + mAttrName = attrName; + } + + @Override + public boolean handle(String nodeName, Node attr, StringBuilder layoutXml) { + String[] intervals = attr.getNodeName().split("[ ,]"); + String[] dimens = new String[intervals.length]; + for (int i = 0; i < intervals.length; i++) { + dimens[i] = DimenHandler.convertToAndroidDimen(intervals[i]); + } + String left, top, right, bottom; + switch (dimens.length) { + case 1: + left = top = right = bottom = dimens[0]; + break; + case 2: + top = bottom = dimens[0]; + left = right = dimens[1]; + break; + case 3: + top = dimens[0]; + left = right = dimens[1]; + bottom = dimens[2]; + break; + case 4: + top = dimens[0]; + right = dimens[1]; + bottom = dimens[2]; + left = dimens[3]; + break; + default: + return false; + } + layoutXml.append("android:").append(mAttrName).append("Top=\"").append(top).append("\"\n") + .append("android:").append(mAttrName).append("Right=\"").append(right).append("\"\n") + .append("android:").append(mAttrName).append("Bottom=\"").append(bottom).append("\"\n") + .append("android:").append(mAttrName).append("Left=\"").append(left).append("\"\n"); + return true; + } + + } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/ConvertLayoutInflater.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/ConvertLayoutInflater.java index 399d1ee6..2e0645d9 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/ConvertLayoutInflater.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/ConvertLayoutInflater.java @@ -7,6 +7,7 @@ import android.view.View; import android.widget.FrameLayout; import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflator; +import com.stardust.autojs.runtime.api.ui.widget.JsFrameLayout; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; @@ -24,7 +25,7 @@ public class ConvertLayoutInflater implements JsLayoutInflater { public View inflate(Context context, String xml) { try { String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml); - FrameLayout root = new FrameLayout(context); + JsFrameLayout root = new JsFrameLayout(context); DynamicLayoutInflator.inflate(context, androidLayoutXml, root); return root; } catch (Exception e) { diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/XmlConverter.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/XmlConverter.java index 224f29d4..d2c41302 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/XmlConverter.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/XmlConverter.java @@ -2,6 +2,8 @@ package com.stardust.autojs.runtime.api.ui; import com.stardust.util.MapEntries; +import static com.stardust.autojs.runtime.api.ui.AttributeHandler.*; + import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; @@ -24,20 +26,37 @@ import javax.xml.parsers.ParserConfigurationException; public class XmlConverter { private static final Map NODE_NAME_MAP = new MapEntries() - .entry("linear", "LinearLayout") + .entry("frame", "com.stardust.autojs.runtime.api.ui.widget.JsFrameLayout") + .entry("linear", "com.stardust.autojs.runtime.api.ui.widget.JsLinearLayout") + .entry("relative", "com.stardust.autojs.runtime.api.ui.widget.JsRelativeLayout") .entry("button", "Button") .entry("text", "TextView") .entry("input", "EditText") + .entry("image", "ImageView") .map(); private static final AttributeHandler ATTRIBUTE_HANDLER = new AttributeHandler.AttrNameRouter() - .registerHandler("w", new AttributeHandler.DimenHandler("width")) - .registerHandler("h", new AttributeHandler.DimenHandler("height")) - .registerHandler("id", new AttributeHandler.IdHandler()) - .setDefaultHandler(new AttributeHandler.MappedAttributeHandler() - .putAttrNameMap("align", "layout_gravity") - .putAttrNameMap("bg", "background")); + .handler("w", new DimenHandler("width")) + .handler("h", new DimenHandler("height")) + .handler("size", new DimenHandler("textSize")) + .handler("id", new IdHandler()) + .handler("vertical", new OrientationHandler()) + .handler("margin", new MarginPaddingHandler("layout_margin")) + .handler("padding", new MarginPaddingHandler("padding")) + .handler("marginLeft", new DimenHandler("layout_marginLeft")) + .handler("marginRight", new DimenHandler("layout_marginRight")) + .handler("marginTop", new DimenHandler("layout_marginTop")) + .handler("marginBottom", new DimenHandler("layout_marginBottom")) + .handler("paddingLeft", new DimenHandler("paddingLeft")) + .handler("paddingRight", new DimenHandler("paddingRight")) + .handler("paddingTop", new DimenHandler("paddingTop")) + .handler("paddingBottom", new DimenHandler("paddingBottom")) + .defaultHandler(new MappedAttributeHandler() + .mapName("align", "layout_gravity") + .mapName("bg", "background") + .mapName("color", "textColor") + ); public static String convertToAndroidLayout(String xml) throws IOException, SAXException, ParserConfigurationException { return convertToAndroidLayout(new InputSource(new StringReader(xml))); @@ -67,7 +86,7 @@ public class XmlConverter { if (textContent == null || textContent.isEmpty()) { return; } - if (nodeName.equals("text") || nodeName.equals("button")) + if (nodeName.equals("text") || nodeName.equals("button") || nodeName.equals("input")) layoutXml.append("android:text=\"").append(textContent).append("\"\n"); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsFrameLayout.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsFrameLayout.java new file mode 100644 index 00000000..2c16da5e --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsFrameLayout.java @@ -0,0 +1,41 @@ +package com.stardust.autojs.runtime.api.ui.widget; + +import android.content.Context; +import android.os.Build; +import android.support.annotation.AttrRes; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; +import android.support.annotation.StyleRes; +import android.util.AttributeSet; +import android.view.View; +import android.widget.FrameLayout; + +import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflator; + +/** + * Created by Stardust on 2017/5/14. + */ + +public class JsFrameLayout extends FrameLayout { + public JsFrameLayout(@NonNull Context context) { + super(context); + } + + public JsFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public JsFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public JsFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public View id(String id) { + return DynamicLayoutInflator.findViewByIdString(this, id); + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsLinearLayout.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsLinearLayout.java new file mode 100644 index 00000000..1e6d201b --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsLinearLayout.java @@ -0,0 +1,40 @@ +package com.stardust.autojs.runtime.api.ui.widget; + +import android.content.Context; +import android.os.Build; +import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; + +import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflator; + +/** + * Created by Stardust on 2017/5/14. + */ + +public class JsLinearLayout extends LinearLayout { + + + public JsLinearLayout(Context context) { + super(context); + } + + public JsLinearLayout(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public JsLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public JsLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public View id(String id) { + return DynamicLayoutInflator.findViewByIdString(this, id); + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsRelativeLayout.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsRelativeLayout.java new file mode 100644 index 00000000..8ce5f2ba --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/ui/widget/JsRelativeLayout.java @@ -0,0 +1,37 @@ +package com.stardust.autojs.runtime.api.ui.widget; + +import android.content.Context; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.util.AttributeSet; +import android.view.View; +import android.widget.RelativeLayout; + +import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflator; + +/** + * Created by Stardust on 2017/5/14. + */ + +public class JsRelativeLayout extends RelativeLayout { + public JsRelativeLayout(Context context) { + super(context); + } + + public JsRelativeLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public JsRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public JsRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public View id(String id) { + return DynamicLayoutInflator.findViewByIdString(this, id); + } +}