package loon.html5.gwt;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.core.client.JsArrayNumber;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.dom.client.Element;
import com.google.gwt.resources.client.ExternalTextResource;
import com.google.gwt.resources.client.ResourceCallback;
import com.google.gwt.resources.client.ResourceException;
import com.google.gwt.resources.client.TextResource;
import com.google.gwt.typedarrays.shared.ArrayBuffer;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.xhr.client.ReadyStateChangeHandler;
import com.google.gwt.xhr.client.XMLHttpRequest;
import com.google.gwt.xhr.client.XMLHttpRequest.ResponseType;
public class GWTScriptLoader {
public interface LoadBinaryListener {
public void onLoadBinaryFile(ArrayBuffer buffer);
public void onFaild(int states, String statesText);
}
public interface LoadTextListener {
public void onLoadTextFile(String text);
public void onFaild(int states, String statesText);
}
/**
* 跨域标记,亲测部分浏览器有反作用,慎用
*
* @param elem
* @param state
*/
public static native void setCrossOrigin(Element elem, String state) /*-{
if ('crossOrigin' in elem)
elem.setAttribute('crossOrigin', state);
}-*/;
public static void loadBinaryFile(String url,
final LoadBinaryListener listener) {
XMLHttpRequest request = XMLHttpRequest.create();
request.setResponseType(ResponseType.ArrayBuffer);
request.setOnReadyStateChange(new ReadyStateChangeHandler() {
@Override
public void onReadyStateChange(XMLHttpRequest xhr) {
if (xhr.getResponseArrayBuffer() == null) {
return;
}
if (xhr.getStatus() == 200) {
ArrayBuffer arrayBufer = xhr.getResponseArrayBuffer();
listener.onLoadBinaryFile(arrayBufer);
} else {
listener.onFaild(xhr.getStatus(), xhr.getStatusText());
}
}
});
request.open("GET", url);
request.send();
}
public static void loadTextFile(String url, final LoadTextListener listener) {
try {
new RequestBuilder(RequestBuilder.GET, url).sendRequest(null,
new RequestCallback() {
@Override
public void onResponseReceived(Request request,
Response response) {
listener.onLoadTextFile(response.getText());
}
@Override
public void onError(Request request, Throwable exception) {
listener.onFaild(0, exception.getMessage());
}
});
} catch (RequestException e) {
listener.onFaild(0, e.getMessage());
}
}
public static interface JsArrayMixedCallback {
Object call(JsArrayMixed args);
}
public static native <T> T get(JavaScriptObject o, Object p)/*-{
return o[p];
}-*/;
public static native String getString(JavaScriptObject o, String s)/*-{
return o[s];
}-*/;
public static native int getInt(JavaScriptObject o, String s)/*-{
return o[s];
}-*/;
public static native JavaScriptObject put(JavaScriptObject o, Object pname,
Object val)/*-{
o[pname] = val;
return o;
}-*/;
public static native JavaScriptObject put(JavaScriptObject o, Object pname,
int val)/*-{
o[pname] = val;
return o;
}-*/;
public static native JavaScriptObject put(JavaScriptObject o, Object pname,
double val)/*-{
o[pname] = val;
return o;
}-*/;
public static native JavaScriptObject putObject(JavaScriptObject o,
String pname, JavaScriptObject val)/*-{
o[pname] = val;
return o;
}-*/;
public static native JsArrayString props(JavaScriptObject o)/*-{
var props = [];
for ( var i in o) {
props.push(i + "");
;
}
return props;
}-*/;
public static native JavaScriptObject empty()/*-{
return {};
}-*/;
public static JavaScriptObject obj(Map<String, Object> props) {
JavaScriptObject o = empty();
for (String k : props.keySet()) {
Object val = props.get(k);
put(o, k, val);
}
return o;
}
public static JavaScriptObject obj(Object... m) {
return obj(toMap2(m));
}
private static Map<Object, Object> toMap2(Object... a) {
Map<Object, Object> m = new HashMap<Object, Object>();
for (int i = 0; i < a.length - 1; i = i + 2)
m.put(a[i], a[i + 1]);
return m;
}
public static native JavaScriptObject arrayEmpty()/*-{
return [];
}-*/;
public static native JavaScriptObject arrayPush(JavaScriptObject arr,
JavaScriptObject o)/*-{
arr.push(o);
return arr;
}-*/;
public static List<String> toList(JsArrayString array) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < array.length(); i++) {
list.add(array.get(i));
}
return list;
}
public static <T extends JavaScriptObject> List<T> toList(JsArray<T> array) {
List<T> list = new ArrayList<T>();
for (int i = 0; i < array.length(); i++) {
list.add(array.get(i));
}
return list;
}
public static <E extends JavaScriptObject> JsArray<E> toArray(List<E> list) {
JsArray<E> array = JsArray.createArray().cast();
for (E data : list) {
array.push(data);
}
return array;
}
public static JsArrayNumber toArray(int[] ints) {
JsArrayNumber array = JsArrayNumber.createArray().cast();
for (int i = 0; i < ints.length; i++) {
array.push(ints[i]);
}
return array;
}
public static boolean arrayContains(JsArray<JavaScriptObject> a,
JavaScriptObject val) {
for (int i = 0; i < a.length(); i++) {
JavaScriptObject o = a.get(i);
if (o != null && o.equals(val))
return true;
}
return false;
}
public static boolean arrayContains(JsArrayMixed a, String val) {
for (int i = 0; i < a.length(); i++) {
String o = a.getString(i);
if (o != null && o.equals(val))
return true;
}
return false;
}
public static boolean arrayContains(JsArrayString a, String val) {
for (int i = 0; i < a.length(); i++) {
String o = a.get(i);
if (o != null && o.equals(val))
return true;
}
return false;
}
public static boolean arrayContains(JsArrayNumber a, String val) {
for (int i = 0; i < a.length(); i++) {
Number o = a.get(i);
if (o != null && o.equals(val))
return true;
}
return false;
}
public static JsArrayNumber toJsArray(int[] a) {
JsArrayNumber jsa = (JsArrayNumber) JsArrayNumber.createArray();
for (int i = 0; i < a.length; i++) {
jsa.push(a[i]);
}
return jsa;
}
public static JsArrayNumber toJsArray(double[] a) {
if (a == null) {
return null;
}
JsArrayNumber jsa = (JsArrayNumber) JsArrayNumber.createArray();
for (int i = 0; i < a.length; i++) {
jsa.push(a[i]);
}
return jsa;
}
public static JsArray<JsArrayNumber> toJsArray(double[][] a) {
if (a == null) {
return null;
}
JsArray<JsArrayNumber> jsa = JsArrayNumber.createArray().cast();
for (int i = 0; i < a.length; i++) {
JsArrayNumber row = JsArrayNumber.createArray().cast();
jsa.push(row);
for (int j = 0; j < a[i].length; j++) {
row.push(a[i][j]);
}
}
return jsa;
}
public static JsArray<JsArrayString> toJsArray(String[][] a) {
if (a == null) {
return null;
}
JsArray<JsArrayString> jsa = JsArrayString.createArray().cast();
for (int i = 0; i < a.length; i++) {
JsArrayString row = JsArrayString.createArray().cast();
jsa.push(row);
for (int j = 0; j < a[i].length; j++) {
row.push(a[i][j]);
}
}
return jsa;
}
public static JsArrayString toJsArray(String[] a) {
if (a == null) {
return null;
}
JsArrayString jsa = JsArrayNumber.createArray().<JsArrayString> cast();
for (int i = 0; i < a.length; i++) {
jsa.push(a[i]);
}
return jsa;
}
public static JsArray<JavaScriptObject> toJsArray(JavaScriptObject[] ja) {
if (ja == null) {
return null;
}
JsArray<JavaScriptObject> jsa = JsArray.createArray().cast();
for (JavaScriptObject t : ja) {
jsa.push(t);
}
return jsa;
}
public static JavaScriptObject toJsObject(Object... ja) {
if (ja == null)
return null;
JavaScriptObject jso = JsArray.createObject();
for (int i = 0; i < ja.length; i += 2) {
put(jso, ja[i], ja[i + 1]);
}
return jso;
}
public static JsArray<JavaScriptObject> to2DJsArray(double[][] ja) {
JsArray<JavaScriptObject> jsa = JsArray.createArray().cast();
if (ja == null) {
return jsa;
}
for (int i = 0; i < ja.length; i++) {
jsa.push(toJsArray(ja[i]));
}
return jsa;
}
public static JsArray<JavaScriptObject> to2DJsArray(String[][] ja) {
JsArray<JavaScriptObject> jsa = JsArray.createArray().cast();
if (ja == null) {
return jsa;
}
for (int i = 0; i < ja.length; i++) {
jsa.push(toJsArray(ja[i]));
}
return jsa;
}
public final native static void putBoolean(JavaScriptObject o, String prop,
boolean b)/*-{
if (b) {
o[prop] = true;
} else {
o[prop] = false;
}
}-*/;
public final native static void putNumber(JavaScriptObject o, String prop,
double v) /*-{
o[prop] = v;
}-*/;
public static double[] toJavaDoubleArray(JsArrayNumber a) {
if (a == null)
return null;
double[] dd = new double[a.length()];
for (int i = 0; i < dd.length; i++) {
dd[i] = a.get(i);
}
return dd;
}
public static String[] toJavaStringArray(JsArrayString a) {
if (a == null)
return null;
String[] dd = new String[a.length()];
for (int i = 0; i < dd.length; i++) {
dd[i] = a.get(i);
}
return dd;
}
public static native JavaScriptObject evalObject(String s)/*-{
return $wnd.eval("(" + s + ")");
}-*/;
public static String print(JsArrayMixed a) {
String s = "JSArray[";
for (int i = 0; i < a.length(); i++) {
s += a.getString(i) + ", ";
}
return s + "]";
}
public static native final void arrayRemoveItem(JsArray<?> a, int i)/*-{
a.splice(i, 1)
}-*/;
public static native double getDouble(JavaScriptObject o, String p)/*-{
return o[p];
}-*/;
public static native final String dump(JavaScriptObject obj,
boolean printValues)/*-{
var s = "{";
for ( var i in obj) {
s += i + (printValues ? ": " + obj[i] : "") + ", ";
}
return s + "}";
}-*/;
public static native JavaScriptObject window()/*-{
return $wnd;
}-*/;
public static final native JavaScriptObject toJsFunction(
JsArrayMixedCallback c)/*-{
return $entry(function() {
return c.@loon.html5.gwt.GWTScriptLoader.JsArrayMixedCallback::call(Lcom/google/gwt/core/client/JsArrayMixed;)(arguments);
});
}-*/;
public static void loadFont(String fontJsUrl, Callback<Void, Exception> c) {
ScriptInjector.fromUrl(fontJsUrl).setWindow(window()).setCallback(c)
.inject();
}
public static void loadFont(TextResource fontJs) {
String text = fontJs.getText();
ScriptInjector.fromString(text).setWindow(window()).inject();
}
public static void loadFont(ExternalTextResource fontJs,
final ResourceCallback<TextResource> callback)
throws ResourceException {
fontJs.getText(new ResourceCallback<TextResource>() {
@Override
public void onSuccess(TextResource resource) {
loadFont(resource);
if (callback != null)
callback.onSuccess(resource);
}
@Override
public void onError(ResourceException e) {
if (callback != null)
callback.onError(e);
}
});
}
public static void injectScript(com.google.gwt.safehtml.shared.SafeUri js,
final com.google.gwt.user.client.rpc.AsyncCallback<Void> callback) {
final com.google.gwt.dom.client.ScriptElement[] script = new com.google.gwt.dom.client.ScriptElement[1];
script[0] = com.google.gwt.core.client.ScriptInjector
.fromUrl(js.asString())
.setWindow(com.google.gwt.core.client.ScriptInjector.TOP_WINDOW)
.setCallback(
new com.google.gwt.core.client.Callback<Void, Exception>() {
@Override
public void onSuccess(Void result) {
script[0].removeFromParent();
callback.onSuccess(result);
}
@Override
public void onFailure(Exception reason) {
callback.onFailure(reason);
}
}).inject().cast();
}
public static void injectJavascript(
com.google.gwt.resources.client.TextResource... textResources) {
for (com.google.gwt.resources.client.TextResource textResource : textResources) {
com.google.gwt.core.client.ScriptInjector
.fromString(textResource.getText())
.setWindow(
com.google.gwt.core.client.ScriptInjector.TOP_WINDOW)
.inject();
}
}
public static void injectCss(
com.google.gwt.resources.client.TextResource... textResources) {
for (com.google.gwt.resources.client.TextResource textResource : textResources) {
com.google.gwt.dom.client.StyleInjector.inject(textResource
.getText());
}
}
public static boolean isURL(String src) {
if (src == null || src.trim().length() == 0 || src.startsWith("/")) {
return false;
}
return src.startsWith("file") || src.startsWith("http");
}
}