feat(rhino): java object and class can custom prototype in javascript

This commit is contained in:
hyb1996
2018-04-07 13:22:41 +08:00
parent c39ba26e1f
commit af8823b10f
5 changed files with 165 additions and 6 deletions

View File

@@ -5,7 +5,7 @@ module.exports = function(__runtime__, scope){
var __obj__ = new java.lang.Object();
for(var method in __selector__){
if(!__obj__[method] && !scope[method]){
if(!(method in __obj__) && !(method in scope)){
scope[method] = (function(method) {
return function(){
var s = selector();

View File

@@ -5,6 +5,8 @@ import android.util.Log;
import com.stardust.autojs.BuildConfig;
import com.stardust.autojs.rhino.AndroidContextFactory;
import com.stardust.autojs.rhino.NativeJavaClassWithPrototype;
import com.stardust.autojs.rhino.NativeJavaObjectWithPrototype;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.StringScriptSource;
@@ -15,6 +17,9 @@ import com.stardust.pio.UncheckedIOException;
import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.NativeJavaClass;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.commonjs.module.RequireBuilder;
@@ -28,6 +33,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Stardust on 2017/4/2.
@@ -158,6 +164,9 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
private ConcurrentHashMap<Class, NativeJavaClassWithPrototype> mJavaClasses = new ConcurrentHashMap<>();
@Override
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
if (obj instanceof String) {
@@ -165,11 +174,28 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
}
if (staticType == UiObjectCollection.class) {
return getRuntime().bridges.asArray(obj);
}
return super.wrap(cx, scope, obj, staticType);
}
@Override
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class<?> staticType) {
NativeJavaObjectWithPrototype obj = new NativeJavaObjectWithPrototype(scope, javaObject, staticType);
NativeJavaClassWithPrototype clazz = mJavaClasses.get(obj.getClass());
if (clazz == null) {
clazz = (NativeJavaClassWithPrototype) wrapJavaClass(cx, scope, obj.getClass());
}
obj.setPrototype(clazz);
return obj;
}
@Override
public Scriptable wrapJavaClass(Context cx, Scriptable scope, Class<?> javaClass) {
NativeJavaClassWithPrototype clazz = new NativeJavaClassWithPrototype(scope, javaClass);
mJavaClasses.put(javaClass, clazz);
return clazz;
}
}
private class InterruptibleAndroidContextFactory extends AndroidContextFactory {
@@ -193,10 +219,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
return cx;
}
@Override
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
return super.doTopCall(callable, cx, scope, thisObj, args);
}
}

View File

@@ -0,0 +1,90 @@
package com.stardust.autojs.rhino;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.NativeJavaClass;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.Scriptable;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Stardust on 2018/4/4.
*/
public class NativeJavaClassWithPrototype extends NativeJavaClass {
private static final Object NULL = new Object();
private ConcurrentHashMap<String, Object> mProperties = new ConcurrentHashMap();
public NativeJavaClassWithPrototype(Scriptable scope, Class<?> javaClass) {
super(scope, javaClass);
}
@Override
public boolean has(String name, Scriptable start) {
return mProperties.containsKey(name) || super.has(name, start) || (prototype != null && prototype.has(name, start))
|| name.equals("prototype");
}
@Override
public Object get(String name, Scriptable start) {
if (name.equals("prototype")) {
return prototype;
}
Object value = mProperties.get(name);
if (value != null) {
return unwrapValue(value);
}
try {
value = super.get(name, start);
} catch (EvaluatorException e) {
if (!memberNotFound(e)) {
throw e;
}
}
if (value != Scriptable.NOT_FOUND) {
return value;
}
if (prototype == null) {
return Scriptable.NOT_FOUND;
}
return prototype.get(name, start);
}
private Object unwrapValue(Object value) {
if (value == NULL)
return null;
return value;
}
@Override
public void put(String name, Scriptable start, Object value) {
if (name.equals("prototype")) {
prototype = (Scriptable) value;
return;
}
if (mProperties.containsKey(name)) {
mProperties.put(name, wrapValue(value));
}
try {
super.put(name, start, value);
} catch (EvaluatorException e) {
if (memberNotFound(e)) {
mProperties.put(name, wrapValue(value));
} else {
throw e;
}
}
}
private Object wrapValue(Object value) {
if (value == null)
return NULL;
return value;
}
private static boolean memberNotFound(EvaluatorException e) {
return e.getMessage() != null && e.getMessage().startsWith("Java class \"com.stardust.autojs.rhino.NativeJavaObjectWithPrototype\"");
}
}

View File

@@ -0,0 +1,46 @@
package com.stardust.autojs.rhino;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.Scriptable;
/**
* Created by Stardust on 2018/4/4.
*/
public class NativeJavaObjectWithPrototype extends NativeJavaObject {
public NativeJavaObjectWithPrototype(Scriptable scope, Object javaObject, Class<?> staticType) {
super(scope, javaObject, staticType);
}
@Override
public boolean has(String name, Scriptable start) {
return super.has(name, start) || (prototype != null && prototype.has(name, start))
|| name.equals("prototype");
}
@Override
public Object get(String name, Scriptable start) {
if (name.equals("prototype")) {
return prototype;
}
Object o = super.get(name, start);
if (o != Scriptable.NOT_FOUND) {
return o;
}
if (prototype == null) {
return o;
}
return prototype.get(name, start);
}
@Override
public void put(String name, Scriptable start, Object value) {
if (name.equals("prototype")) {
prototype = (Scriptable) value;
return;
}
super.put(name, start, value);
}
}

View File

@@ -54,6 +54,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
@Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
instance = this;
Log.v(TAG, "onAccessibilityEvent: " + event);
if (!containsAllEventTypes && !eventTypes.contains(event.getEventType()))
return;