feat(rhino): java object and class can custom prototype in javascript
This commit is contained in:
@@ -5,7 +5,7 @@ module.exports = function(__runtime__, scope){
|
|||||||
var __obj__ = new java.lang.Object();
|
var __obj__ = new java.lang.Object();
|
||||||
|
|
||||||
for(var method in __selector__){
|
for(var method in __selector__){
|
||||||
if(!__obj__[method] && !scope[method]){
|
if(!(method in __obj__) && !(method in scope)){
|
||||||
scope[method] = (function(method) {
|
scope[method] = (function(method) {
|
||||||
return function(){
|
return function(){
|
||||||
var s = selector();
|
var s = selector();
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.stardust.autojs.BuildConfig;
|
import com.stardust.autojs.BuildConfig;
|
||||||
import com.stardust.autojs.rhino.AndroidContextFactory;
|
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.runtime.exception.ScriptInterruptedException;
|
||||||
import com.stardust.autojs.script.JavaScriptSource;
|
import com.stardust.autojs.script.JavaScriptSource;
|
||||||
import com.stardust.autojs.script.StringScriptSource;
|
import com.stardust.autojs.script.StringScriptSource;
|
||||||
@@ -15,6 +17,9 @@ import com.stardust.pio.UncheckedIOException;
|
|||||||
import org.mozilla.javascript.Callable;
|
import org.mozilla.javascript.Callable;
|
||||||
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Context;
|
||||||
import org.mozilla.javascript.ImporterTopLevel;
|
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.Scriptable;
|
||||||
import org.mozilla.javascript.ScriptableObject;
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
import org.mozilla.javascript.commonjs.module.RequireBuilder;
|
import org.mozilla.javascript.commonjs.module.RequireBuilder;
|
||||||
@@ -28,6 +33,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/4/2.
|
* 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 class WrapFactory extends org.mozilla.javascript.WrapFactory {
|
||||||
|
|
||||||
|
|
||||||
|
private ConcurrentHashMap<Class, NativeJavaClassWithPrototype> mJavaClasses = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
|
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
|
||||||
if (obj instanceof String) {
|
if (obj instanceof String) {
|
||||||
@@ -165,11 +174,28 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
}
|
}
|
||||||
if (staticType == UiObjectCollection.class) {
|
if (staticType == UiObjectCollection.class) {
|
||||||
return getRuntime().bridges.asArray(obj);
|
return getRuntime().bridges.asArray(obj);
|
||||||
|
|
||||||
}
|
}
|
||||||
return super.wrap(cx, scope, obj, staticType);
|
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 {
|
private class InterruptibleAndroidContextFactory extends AndroidContextFactory {
|
||||||
@@ -193,10 +219,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
|
|
||||||
return super.doTopCall(callable, cx, scope, thisObj, args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,6 +54,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccessibilityEvent(final AccessibilityEvent event) {
|
public void onAccessibilityEvent(final AccessibilityEvent event) {
|
||||||
|
instance = this;
|
||||||
Log.v(TAG, "onAccessibilityEvent: " + event);
|
Log.v(TAG, "onAccessibilityEvent: " + event);
|
||||||
if (!containsAllEventTypes && !eventTypes.contains(event.getEventType()))
|
if (!containsAllEventTypes && !eventTypes.contains(event.getEventType()))
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user