Merge "Improve TTS engine audio buffer API"
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 6c6a72d..328a55b 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1086,7 +1086,7 @@
/**
* Area class for focus.
*
- * @see #setFocusAreas(List<Area>)
+ * @see #setFocusAreas(List)
* @see #getFocusAreas()
* @hide
*/
@@ -2573,8 +2573,8 @@
/**
* Gets the maximum number of focus areas supported. This is the maximum
- * length of the list in {@link #setFocusArea(List<Area>)} and
- * {@link #getFocusArea()}.
+ * length of the list in {@link #setFocusAreas(List)} and
+ * {@link #getFocusAreas()}.
*
* @return the maximum number of focus areas supported by the camera.
* @see #getFocusAreas()
@@ -2588,8 +2588,8 @@
* Gets the current focus areas. Camera driver uses the areas to decide
* focus.
*
- * Before using this API or {@link #setFocusAreas(List<int>)}, apps
- * should call {@link #getMaxNumFocusArea()} to know the maximum number of
+ * Before using this API or {@link #setFocusAreas(List)}, apps should
+ * call {@link #getMaxNumFocusAreas()} to know the maximum number of
* focus areas first. If the value is 0, focus area is not supported.
*
* Each focus area is a rectangle with specified weight. The direction
@@ -2618,7 +2618,7 @@
*
* Focus area only has effect if the current focus mode is
* {@link #FOCUS_MODE_AUTO}, {@link #FOCUS_MODE_MACRO}, or
- * {@link #FOCUS_MODE_CONTINOUS_VIDEO}.
+ * {@link #FOCUS_MODE_CONTINUOUS_VIDEO}.
*
* @return a list of current focus areas
* @hide
@@ -2630,7 +2630,7 @@
/**
* Sets focus areas. See {@link #getFocusAreas()} for documentation.
*
- * @param focusArea the focus areas
+ * @param focusAreas the focus areas
* @see #getFocusAreas()
* @hide
*/
@@ -2640,8 +2640,8 @@
/**
* Gets the maximum number of metering areas supported. This is the
- * maximum length of the list in {@link #setMeteringArea(List<Area>)}
- * and {@link #getMeteringArea()}.
+ * maximum length of the list in {@link #setMeteringAreas(List)} and
+ * {@link #getMeteringAreas()}.
*
* @return the maximum number of metering areas supported by the camera.
* @see #getMeteringAreas()
@@ -2655,10 +2655,10 @@
* Gets the current metering areas. Camera driver uses these areas to
* decide exposure.
*
- * Before using this API or {@link #setMeteringAreas(List<int>)}, apps
- * should call {@link #getMaxNumMeteringArea()} to know the maximum
- * number of metering areas first. If the value is 0, metering area is
- * not supported.
+ * Before using this API or {@link #setMeteringAreas(List)}, apps should
+ * call {@link #getMaxNumMeteringAreas()} to know the maximum number of
+ * metering areas first. If the value is 0, metering area is not
+ * supported.
*
* Each metering area is a rectangle with specified weight. The
* direction is relative to the sensor orientation, that is, what the
@@ -2685,7 +2685,7 @@
* even when using zoom.
*
* No matter what metering areas are, the final exposure are compensated
- * by {@link setExposureCompensation(int)}.
+ * by {@link #setExposureCompensation(int)}.
*
* @return a list of current metering areas
* @hide
@@ -2698,7 +2698,7 @@
* Sets metering areas. See {@link #getMeteringAreas()} for
* documentation.
*
- * @param meteringArea the metering areas
+ * @param meteringAreas the metering areas
* @see #getMeteringAreas()
* @hide
*/
diff --git a/core/java/android/webkit/webdriver/By.java b/core/java/android/webkit/webdriver/By.java
new file mode 100644
index 0000000..b40351d
--- /dev/null
+++ b/core/java/android/webkit/webdriver/By.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit.webdriver;
+
+/**
+ * Mechanism to locate elements within the DOM of the page.
+ * @hide
+ */
+public abstract class By {
+ public abstract WebElement findElement(WebElement element);
+
+ /**
+ * Locates an element by its HTML id attribute.
+ *
+ * @param id The HTML id attribute to look for.
+ * @return A By instance that locates elements by their HTML id attributes.
+ */
+ public static By id(final String id) {
+ throwIfNull(id);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementById(id);
+ }
+
+ @Override
+ public String toString() {
+ return "By.id: " + id;
+ }
+ };
+ }
+
+ /**
+ * Locates an element by the matching the exact text on the HTML link.
+ *
+ * @param linkText The exact text to match against.
+ * @return A By instance that locates elements by the text displayed by
+ * the link.
+ */
+ public static By linkText(final String linkText) {
+ throwIfNull(linkText);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByLinkText(linkText);
+ }
+
+ @Override
+ public String toString() {
+ return "By.linkText: " + linkText;
+ }
+ };
+ }
+
+ /**
+ * Locates an element by matching partial part of the text displayed by an
+ * HTML link.
+ *
+ * @param linkText The text that should be contained by the text displayed
+ * on the link.
+ * @return A By instance that locates elements that contain the given link
+ * text.
+ */
+ public static By partialLinkText(final String linkText) {
+ throwIfNull(linkText);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByPartialLinkText(linkText);
+ }
+
+ @Override
+ public String toString() {
+ return "By.partialLinkText: " + linkText;
+ }
+ };
+ }
+
+ /**
+ * Locates an element by matching its HTML name attribute.
+ *
+ * @param name The value of the HTML name attribute.
+ * @return A By instance that locates elements by the HTML name attribute.
+ */
+ public static By name(final String name) {
+ throwIfNull(name);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByName(name);
+ }
+
+ @Override
+ public String toString() {
+ return "By.name: " + name;
+ }
+ };
+ }
+
+ /**
+ * Locates an element by matching its class name.
+ * @param className The class name
+ * @return A By instance that locates elements by their class name attribute.
+ */
+ public static By className(final String className) {
+ throwIfNull(className);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByClassName(className);
+ }
+
+ @Override
+ public String toString() {
+ return "By.className: " + className;
+ }
+ };
+ }
+
+ /**
+ * Locates an element by matching its css property.
+ *
+ * @param css The css property.
+ * @return A By instance that locates elements by their css property.
+ */
+ public static By css(final String css) {
+ throwIfNull(css);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByCss(css);
+ }
+
+ @Override
+ public String toString() {
+ return "By.css: " + css;
+ }
+ };
+ }
+
+ /**
+ * Locates an element by matching its HTML tag name.
+ *
+ * @param tagName The HTML tag name to look for.
+ * @return A By instance that locates elements using the name of the
+ * HTML tag.
+ */
+ public static By tagName(final String tagName) {
+ throwIfNull(tagName);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByTagName(tagName);
+ }
+
+ @Override
+ public String toString() {
+ return "By.tagName: " + tagName;
+ }
+ };
+ }
+
+ /**
+ * Locates an element using an XPath expression.
+ *
+ * <p>When using XPath, be aware that this follows standard conventions: a
+ * search prefixed with "//" will search the entire document, not just the
+ * children of the current node. Use ".//" to limit your search to the
+ * children of this {@link android.webkit.webdriver.WebElement}.
+ *
+ * @param xpath The XPath expression to use.
+ * @return A By instance that locates elements using the given XPath.
+ */
+ public static By xpath(final String xpath) {
+ throwIfNull(xpath);
+ return new By() {
+ @Override
+ public WebElement findElement(WebElement element) {
+ return element.findElementByXPath(xpath);
+ }
+
+ @Override
+ public String toString() {
+ return "By.xpath: " + xpath;
+ }
+ };
+ }
+
+ private static void throwIfNull(String argument) {
+ if (argument == null) {
+ throw new IllegalArgumentException(
+ "Cannot find elements with null locator.");
+ }
+ }
+}
diff --git a/core/java/android/webkit/webdriver/WebDriver.java b/core/java/android/webkit/webdriver/WebDriver.java
index 7a25390..90e701f 100644
--- a/core/java/android/webkit/webdriver/WebDriver.java
+++ b/core/java/android/webkit/webdriver/WebDriver.java
@@ -16,20 +16,27 @@
package android.webkit.webdriver;
-import android.graphics.Bitmap;
-import android.net.Uri;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
+import com.android.internal.R;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import android.os.Handler;
import android.os.Message;
-import android.view.View;
-import android.webkit.ConsoleMessage;
-import android.webkit.GeolocationPermissions;
-import android.webkit.JsPromptResult;
-import android.webkit.JsResult;
-import android.webkit.ValueCallback;
-import android.webkit.WebChromeClient;
-import android.webkit.WebStorage;
import android.webkit.WebView;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
/**
* Drives a web application by controlling the WebView. This class
* provides a DOM-like API allowing to get information about the page,
@@ -68,27 +75,34 @@
* mDriver = getActivity().getDriver();
* }
*
- * public void testGetIsBlocking() {
+ * public void testGoogle() {
* mDriver.get("http://google.com");
- * assertTrue(mDriver.getPageSource().startsWith("<html"));
+ * WebElement searchBox = mDriver.findElement(By.name("q"));
+ * q.sendKeys("Cheese!");
+ * q.submit();
+ * assertTrue(mDriver.findElements(By.partialLinkText("Cheese")).size() > 0);
* }
*}
*
* @hide
*/
public class WebDriver {
- // Timeout for page load in milliseconds
+ // Timeout for page load in milliseconds.
private static final int LOADING_TIMEOUT = 30000;
- // Timeout for executing JavaScript in the WebView in milliseconds
+ // Timeout for executing JavaScript in the WebView in milliseconds.
private static final int JS_EXECUTION_TIMEOUT = 10000;
// Commands posted to the handler
- private static final int GET_URL = 1;
- private static final int EXECUTE_SCRIPT = 2;
+ private static final int CMD_GET_URL = 1;
+ private static final int CMD_EXECUTE_SCRIPT = 2;
+
+ private static final String ELEMENT_KEY = "ELEMENT";
+ private static final String STATUS = "status";
+ private static final String VALUE = "value";
private static final long MAIN_THREAD = Thread.currentThread().getId();
- // This is updated by a callabck from JavaScript when the result is ready
+ // This is updated by a callabck from JavaScript when the result is ready.
private String mJsResult;
// Used for synchronization
@@ -99,30 +113,84 @@
private WebView mWebView;
- // This Handler runs in the main UI thread
+ // This WebElement represents the object document.documentElement
+ private WebElement mDocumentElement;
+
+ // This Handler runs in the main UI thread.
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- if (msg.what == GET_URL) {
+ if (msg.what == CMD_GET_URL) {
final String url = (String) msg.obj;
mWebView.loadUrl(url);
- } else if (msg.what == EXECUTE_SCRIPT) {
- executeScript((String) msg.obj);
+ } else if (msg.what == CMD_EXECUTE_SCRIPT) {
+ mWebView.loadUrl("javascript:" + (String) msg.obj);
}
}
};
+ /**
+ * Error codes from the WebDriver wire protocol
+ * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
+ */
+ private enum ErrorCode {
+ SUCCESS(0),
+ NO_SUCH_ELEMENT(7),
+ NO_SUCH_FRAME(8),
+ UNKNOWN_COMMAND(9),
+ UNSUPPORTED_OPERATION(9), // Alias
+ STALE_ELEMENT_REFERENCE(10),
+ ELEMENT_NOT_VISISBLE(11),
+ INVALID_ELEMENT_STATE(12),
+ UNKNOWN_ERROR(13),
+ ELEMENT_NOT_SELECTABLE(15),
+ XPATH_LOOKUP_ERROR(19),
+ NO_SUCH_WINDOW(23),
+ INVALID_COOKIE_DOMAIN(24),
+ UNABLE_TO_SET_COOKIE(25),
+ MODAL_DIALOG_OPENED(26),
+ MODAL_DIALOG_OPEN(27),
+ SCRIPT_TIMEOUT(28);
+
+ private final int mCode;
+ private static ErrorCode[] values = ErrorCode.values();
+
+ ErrorCode(int code) {
+ this.mCode = code;
+ }
+
+ public int getCode() {
+ return mCode;
+ }
+
+ public static ErrorCode get(final int intValue) {
+ for (int i = 0; i < values.length; i++) {
+ if (values[i].getCode() == intValue) {
+ return values[i];
+ }
+ }
+ throw new IllegalArgumentException(intValue
+ + " does not map to any ErrorCode.");
+ }
+ }
+
public WebDriver(WebView webview) {
+ this.mWebView = webview;
+ if (mWebView == null) {
+ throw new IllegalArgumentException("WebView cannot be null");
+ }
if (!mWebView.getSettings().getJavaScriptEnabled()) {
throw new RuntimeException("Javascript is disabled in the WebView. "
+ "Enable it to use WebDriver");
}
shouldRunInMainThread(true);
+
mSyncObject = new Object();
this.mWebView = webview;
WebchromeClientWrapper chromeWrapper = new WebchromeClientWrapper(
webview.getWebChromeClient(), this);
mWebView.setWebChromeClient(chromeWrapper);
+ mDocumentElement = new WebElement(this, "");
mWebView.addJavascriptInterface(new JavascriptResultReady(),
"webdriver");
}
@@ -134,21 +202,263 @@
* @param url The URL to load.
*/
public void get(String url) {
- executeCommand(GET_URL, url, LOADING_TIMEOUT);
+ executeCommand(CMD_GET_URL, url, LOADING_TIMEOUT);
}
/**
* @return The source page of the currently loaded page in WebView.
*/
public String getPageSource() {
- executeCommand(EXECUTE_SCRIPT, "return (new XMLSerializer())"
- + ".serializeToString(document.documentElement);",
- JS_EXECUTION_TIMEOUT);
- return mJsResult;
+ return (String) executeScript("return new XMLSerializer()."
+ + "serializeToString(document);");
}
- private void executeScript(String script) {
- mWebView.loadUrl("javascript:" + script);
+ /**
+ * Find the first {@link android.webkit.webdriver.WebElement} using the
+ * given method.
+ *
+ * @param by The locating mechanism to use.
+ * @return The first matching element on the current context.
+ * @throws {@link android.webkit.webdriver.WebElementNotFoundException} if
+ * no matching element was found.
+ */
+ public WebElement findElement(By by) {
+ return by.findElement(mDocumentElement);
+ }
+
+ /**
+ * Clears the WebView.
+ */
+ public void quit() {
+ mWebView.clearCache(true);
+ mWebView.clearFormData();
+ mWebView.clearHistory();
+ mWebView.clearSslPreferences();
+ mWebView.clearView();
+ }
+
+ /**
+ * Executes javascript in the context of the main frame.
+ *
+ * If the script has a return value the following happens:
+ * <ul>
+ * <li>For an HTML element, this method returns a WebElement</li>
+ * <li>For a decimal, a Double is returned</li>
+ * <li>For non-decimal number, a Long is returned</li>
+ * <li>For a boolean, a Boolean is returned</li>
+ * <li>For all other cases, a String is returned</li>
+ * <li>For an array, this returns a List<Object> with each object
+ * following the rules above.</li>
+ * <li>For an object literal this returns a Map<String, Object>. Note that
+ * Object literals keys can only be Strings. Non Strings keys will
+ * be filtered out.</li>
+ * </ul>
+ *
+ * <p> Arguments must be a number, a boolean, a string a WebElement or
+ * a list of any combination of the above. The arguments will be made
+ * available to the javascript via the "arguments" magic variable,
+ * as if the function was called via "Function.apply".
+ *
+ * @param script The JavaScript to execute.
+ * @param args The arguments to the script. Can be any of a number, boolean,
+ * string, WebElement or a List of those.
+ * @return A Boolean, Long, Double, String, WebElement, List or null.
+ */
+ public Object executeScript(final String script, final Object... args) {
+ String scriptArgs = "[" + convertToJsArgs(args) + "]";
+ String injectScriptJs = getResourceAsString(R.raw.execute_script_android);
+ return executeRawJavascript("(" + injectScriptJs +
+ ")(" + escapeAndQuote(script) + ", " + scriptArgs + ", true)");
+ }
+
+ /**
+ * Converts the arguments passed to a JavaScript friendly format.
+ *
+ * @param args The arguments to convert.
+ * @return Comma separated Strings containing the arguments.
+ */
+ /*package*/ String convertToJsArgs(final Object... args) {
+ StringBuilder toReturn = new StringBuilder();
+ int length = args.length;
+ for (int i = 0; i < length; i++) {
+ toReturn.append((i > 0) ? "," : "");
+ if (args[i] instanceof List<?>) {
+ toReturn.append("[");
+ List<Object> aList = (List<Object>) args[i];
+ for (int j = 0 ; j < aList.size(); j++) {
+ String comma = ((j == 0) ? "" : ",");
+ toReturn.append(comma + convertToJsArgs(aList.get(j)));
+ }
+ toReturn.append("]");
+ } else if (args[i] instanceof Map<?, ?>) {
+ Map<Object, Object> aMap = (Map<Object, Object>) args[i];
+ String toAdd = "{";
+ for (Object key: aMap.keySet()) {
+ toAdd += key + ":"
+ + convertToJsArgs(aMap.get(key)) + ",";
+ }
+ toReturn.append(toAdd.substring(0, toAdd.length() -1) + "}");
+ } else if (args[i] instanceof WebElement) {
+ // WebElement are represented in JavaScript by Objects as
+ // follow: {ELEMENT:"id"}
+ toReturn.append("{" + ELEMENT_KEY + ":\""
+ + ((WebElement) args[i]).getId() + "\"}");
+ } else if (args[i] instanceof Number || args[i] instanceof Boolean) {
+ toReturn.append(String.valueOf(args[i]));
+ } else if (args[i] instanceof String) {
+ toReturn.append(escapeAndQuote((String) args[i]));
+ } else {
+ throw new IllegalArgumentException(
+ "Javascript arguments can be "
+ + "a Number, a Boolean, a String, a WebElement, "
+ + "or a List or a Map of those. Got: "
+ + ((args[i] == null) ? "null" : args[i].toString()));
+ }
+ }
+ return toReturn.toString();
+ }
+
+ /*package*/ Object executeRawJavascript(final String script) {
+ String result = executeCommand(CMD_EXECUTE_SCRIPT,
+ "window.webdriver.resultReady(" + script + ")",
+ JS_EXECUTION_TIMEOUT);
+ try {
+ JSONObject json = new JSONObject(result);
+ throwIfError(json);
+ Object value = json.get(VALUE);
+ return convertJsonToJavaObject(value);
+ } catch (JSONException e) {
+ throw new RuntimeException("Failed to parse JavaScript result: "
+ + result.toString(), e);
+ }
+ }
+
+ /*package*/ String getResourceAsString(final int resourceId) {
+ InputStream is = mWebView.getResources().openRawResource(resourceId);
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ try {
+ while ((line = br.readLine()) != null) {
+ sb.append(line);
+ }
+ br.close();
+ is.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to open JavaScript resource.", e);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Wraps the given string into quotes and escape existing quotes
+ * and backslashes.
+ * "foo" -> "\"foo\""
+ * "foo\"" -> "\"foo\\\"\""
+ * "fo\o" -> "\"fo\\o\""
+ *
+ * @param toWrap The String to wrap in quotes
+ * @return a String wrapping the original String in quotes
+ */
+ private static String escapeAndQuote(final String toWrap) {
+ StringBuilder toReturn = new StringBuilder("\"");
+ for (int i = 0; i < toWrap.length(); i++) {
+ char c = toWrap.charAt(i);
+ if (c == '\"') {
+ toReturn.append("\\\"");
+ } else if (c == '\\') {
+ toReturn.append("\\\\");
+ } else {
+ toReturn.append(c);
+ }
+ }
+ toReturn.append("\"");
+ return toReturn.toString();
+ }
+
+ private Object convertJsonToJavaObject(final Object toConvert) {
+ try {
+ if (toConvert == null
+ || toConvert.equals(null)
+ || "undefined".equals(toConvert)
+ || "null".equals(toConvert)) {
+ return null;
+ } else if (toConvert instanceof Boolean) {
+ return toConvert;
+ } else if (toConvert instanceof Double
+ || toConvert instanceof Float) {
+ return Double.valueOf(String.valueOf(toConvert));
+ } else if (toConvert instanceof Integer
+ || toConvert instanceof Long) {
+ return Long.valueOf(String.valueOf(toConvert));
+ } else if (toConvert instanceof JSONArray) { // List
+ return convertJsonArrayToList((JSONArray) toConvert);
+ } else if (toConvert instanceof JSONObject) { // Map or WebElment
+ JSONObject map = (JSONObject) toConvert;
+ if (map.opt(ELEMENT_KEY) != null) { // WebElement
+ return new WebElement(this, (String) map.get(ELEMENT_KEY));
+ } else { // Map
+ return convertJsonObjectToMap(map);
+ }
+ } else {
+ return toConvert.toString();
+ }
+ } catch (JSONException e) {
+ throw new RuntimeException("Failed to parse JavaScript result: "
+ + toConvert.toString(), e);
+ }
+ }
+
+ private List<Object> convertJsonArrayToList(final JSONArray json) {
+ List<Object> toReturn = Lists.newArrayList();
+ for (int i = 0; i < json.length(); i++) {
+ try {
+ toReturn.add(convertJsonToJavaObject(json.get(i)));
+ } catch (JSONException e) {
+ throw new RuntimeException("Failed to parse JSON: "
+ + json.toString(), e);
+ }
+ }
+ return toReturn;
+ }
+
+ private Map<Object, Object> convertJsonObjectToMap(final JSONObject json) {
+ Map<Object, Object> toReturn = Maps.newHashMap();
+ for (Iterator it = json.keys(); it.hasNext();) {
+ String key = (String) it.next();
+ try {
+ Object value = json.get(key);
+ toReturn.put(convertJsonToJavaObject(key),
+ convertJsonToJavaObject(value));
+ } catch (JSONException e) {
+ throw new RuntimeException("Failed to parse JSON:"
+ + json.toString(), e);
+ }
+ }
+ return toReturn;
+ }
+
+ private void throwIfError(final JSONObject jsonObject) {
+ ErrorCode status;
+ String errorMsg;
+ try {
+ status = ErrorCode.get((Integer) jsonObject.get(STATUS));
+ errorMsg = String.valueOf(jsonObject.get(VALUE));
+ } catch (JSONException e) {
+ throw new RuntimeException("Failed to parse JSON Object: "
+ + jsonObject, e);
+ }
+ switch (status) {
+ case SUCCESS:
+ return;
+ case NO_SUCH_ELEMENT:
+ throw new WebElementNotFoundException("Could not find "
+ + "WebElement.");
+ case STALE_ELEMENT_REFERENCE:
+ throw new WebElementStaleException("WebElement is stale.");
+ default:
+ throw new RuntimeException("Error: " + errorMsg);
+ }
}
private void shouldRunInMainThread(boolean value) {
@@ -167,7 +477,7 @@
*
* @param result The result that should be sent to Java from Javascript.
*/
- public void resultReady(String result) {
+ public void resultReady(final String result) {
synchronized (mSyncObject) {
mJsResult = result;
mCommandDone = true;
@@ -191,9 +501,8 @@
* @param arg The argument for that command.
* @param timeout A timeout in milliseconds.
*/
- private void executeCommand(int command, String arg, long timeout) {
+ private String executeCommand(int command, final Object arg, long timeout) {
shouldRunInMainThread(false);
-
synchronized (mSyncObject) {
mCommandDone = false;
Message msg = mHandler.obtainMessage(command);
@@ -212,5 +521,6 @@
}
}
}
+ return mJsResult;
}
}
diff --git a/core/java/android/webkit/webdriver/WebElement.java b/core/java/android/webkit/webdriver/WebElement.java
new file mode 100644
index 0000000..384d55f
--- /dev/null
+++ b/core/java/android/webkit/webdriver/WebElement.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit.webdriver;
+
+import com.android.internal.R;
+
+/**
+ * Represents an HTML element. Typically most interactions with a web page
+ * will be performed through this class.
+ *
+ * @hide
+ */
+public class WebElement {
+ private final String mId;
+ private final WebDriver mDriver;
+
+ /**
+ * Package constructor to prevent clients from creating a new WebElement
+ * instance.
+ *
+ * <p> A WebElement represents an HTML element on the page.
+ * The corresponding HTML element is stored in a JS cache in the page
+ * that can be accessed through JavaScript using "bot.inject.cache".
+ *
+ * @param driver The WebDriver instance to use.
+ * @param id The index of the HTML element in the JavaSctipt cache. Pass
+ * an empty String to indicate that this is the
+ * document.documentElement object.
+ */
+ /* Package */ WebElement(final WebDriver driver, final String id) {
+ this.mId = id;
+ this.mDriver = driver;
+ }
+
+ /**
+ * Finds the first {@link android.webkit.webdriver.WebElement} using the
+ * given method.
+ *
+ * @param by The locating mechanism to use.
+ * @return The first matching element on the current context.
+ */
+ public WebElement findElement(final By by) {
+ return by.findElement(this);
+ }
+
+ /**
+ * Gets the visisble (i.e. not hidden by CSS) innerText of this element,
+ * inlcuding sub-elements.
+ *
+ * @return the innerText of this element.
+ * @throws {@link android.webkit.webdriver.WebElementStaleException} if this
+ * element is stale, i.e. not on the current DOM.
+ */
+ public String getText() {
+ String getText = mDriver.getResourceAsString(R.raw.get_text_android);
+ if (mId.equals("")) {
+ return null;
+ }
+ return (String) executeAtom(getText, this);
+ }
+
+ /*package*/ String getId() {
+ return mId;
+ }
+
+ /* package */ WebElement findElementById(final String locator) {
+ return findElement("id", locator);
+ }
+
+ /* package */ WebElement findElementByLinkText(final String linkText) {
+ return findElement("linkText", linkText);
+ }
+
+ /* package */ WebElement findElementByPartialLinkText(
+ final String linkText) {
+ return findElement("partialLinkText", linkText);
+ }
+
+ /* package */ WebElement findElementByName(final String name) {
+ return findElement("name", name);
+ }
+
+ /* package */ WebElement findElementByClassName(final String className) {
+ return findElement("className", className);
+ }
+
+ /* package */ WebElement findElementByCss(final String css) {
+ return findElement("css", css);
+ }
+
+ /* package */ WebElement findElementByTagName(final String tagName) {
+ return findElement("tagName", tagName);
+ }
+
+ /* package */ WebElement findElementByXPath(final String xpath) {
+ return findElement("xpath", xpath);
+ }
+
+ private Object executeAtom(final String atom, final Object... args) {
+ String scriptArgs = mDriver.convertToJsArgs(args);
+ return mDriver.executeRawJavascript("(" +
+ atom + ")(" + scriptArgs + ")");
+ }
+
+ private WebElement findElement(String strategy, String locator) {
+ String findElement = mDriver.getResourceAsString(
+ R.raw.find_element_android);
+ WebElement el;
+ if (mId.equals("")) {
+ // Use default as root which is the document object
+ el = (WebElement) executeAtom(findElement, strategy, locator);
+ } else {
+ // Use this as root
+ el = (WebElement) executeAtom(findElement, strategy, locator, this);
+ }
+ if (el == null) {
+ throw new WebElementNotFoundException("Could not find element "
+ + "with " + strategy + ": " + locator);
+ }
+ return el;
+ }
+}
diff --git a/core/java/android/webkit/webdriver/WebElementNotFoundException.java b/core/java/android/webkit/webdriver/WebElementNotFoundException.java
new file mode 100644
index 0000000..e66d279
--- /dev/null
+++ b/core/java/android/webkit/webdriver/WebElementNotFoundException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit.webdriver;
+
+/**
+ * Thrown when a {@link android.webkit.webdriver.WebElement} is not found in the
+ * DOM of the page.
+ * @hide
+ */
+public class WebElementNotFoundException extends RuntimeException {
+
+ public WebElementNotFoundException() {
+ super();
+ }
+
+ public WebElementNotFoundException(String reason) {
+ super(reason);
+ }
+
+ public WebElementNotFoundException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
+
+ public WebElementNotFoundException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/core/java/android/webkit/webdriver/WebElementStaleException.java b/core/java/android/webkit/webdriver/WebElementStaleException.java
new file mode 100644
index 0000000..c59e794
--- /dev/null
+++ b/core/java/android/webkit/webdriver/WebElementStaleException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit.webdriver;
+
+/**
+ * Thrown when trying to access a {@link android.webkit.webdriver.WebElement}
+ * that is stale. This mean that the {@link android.webkit.webdriver.WebElement}
+ * is no longer present on the DOM of the page.
+ * @hide
+ */
+public class WebElementStaleException extends RuntimeException {
+
+ public WebElementStaleException() {
+ super();
+ }
+
+ public WebElementStaleException(String reason) {
+ super(reason);
+ }
+
+ public WebElementStaleException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
+
+ public WebElementStaleException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/core/res/res/raw/execute_script_android.js b/core/res/res/raw/execute_script_android.js
new file mode 100644
index 0000000..d145754
--- /dev/null
+++ b/core/res/res/raw/execute_script_android.js
@@ -0,0 +1,8 @@
+function(){return function(){function h(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(b=="function"&&typeof a.call=="undefined")return"object";return b}function i(a){var b=h(a);return b=="array"||b=="object"&&typeof a.length=="number"}function j(a){a=h(a);return a=="object"||a=="array"||a=="function"}var k=Date.now||function(){return+new Date};function l(a,b){function c(){}c.prototype=b.prototype;a.c=b.prototype;a.prototype=new c};function m(a){this.stack=Error().stack||"";if(a)this.message=String(a)}l(m,Error);m.prototype.name="CustomError";function n(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function o(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function p(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function q(a,b){m.call(this,b);this.code=a;this.name=r[a]||r[13]}l(q,m);var r,s={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},t={};for(var u in s)t[s[u]]=u;r=t;
+q.prototype.toString=function(){return"["+this.name+"] "+this.message};function v(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a};function w(a,b){b.unshift(a);m.call(this,v.apply(null,b));b.shift();this.b=a}l(w,m);w.prototype.name="AssertionError";function x(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new w(""+d,e||[]);}return a};var y=Array.prototype,z=y.map?function(a,b,c){x(a.length!=null);return y.map.call(a,b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=typeof a=="string"?a.split(""):a;for(var g=0;g<d;g++)if(g in f)e[g]=b.call(c,f[g],g,a);return e};var A="",B;if(B=/WebKit\/(\S+)/){var C=B.exec(this.navigator?this.navigator.userAgent:null);A=C?C[1]:""};function D(){}
+function E(a,b,c){switch(typeof b){case "string":F(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(h(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);E(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);F(a,e,c);c.push(":");E(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var G={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},H=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function F(a,b,c){c.push('"',b.replace(H,function(d){if(d in G)return G[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return G[d]=f+e.toString(16)}),'"')};function I(a){switch(h(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return z(a,I);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=J(a);return b}if(i(a))return z(a,I);a=n(a,function(c,d){return typeof d=="number"||typeof d=="string"});return o(a,I);default:return null}}
+function K(a,b){if(h(a)=="array")return z(a,function(c){return K(c,b)});else if(j(a))return"ELEMENT"in a?L(a.ELEMENT,b):o(a,function(c){return K(c,b)});return a}function M(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.a=k()}return b}function J(a){var b=M(a.ownerDocument),c=p(b,function(d){return d==a});if(!c){c=":wdc:"+b.a++;b[c]=a}return c}
+function L(a,b){a=decodeURIComponent(a);var c=b||document,d=M(c);if(!(a in d))throw new q(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new q(10,"Element is no longer attached to the DOM");};function N(a,b,c){var d;try{if(typeof a=="string")a=new Function(a);var e=K(b),f=a.apply(null,e);d={status:0,value:I(f)}}catch(g){d={status:"code"in g?g.code:13,value:{message:g.message}}}if(c){a=[];E(new D,d,a);d=a.join("")}else d=d;return d}var O="_".split("."),P=this;!(O[0]in P)&&P.execScript&&P.execScript("var "+O[0]);for(var Q;O.length&&(Q=O.shift());)if(!O.length&&N!==undefined)P[Q]=N;else P=P[Q]?P[Q]:P[Q]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/find_element_android.js b/core/res/res/raw/find_element_android.js
new file mode 100644
index 0000000..f493223
--- /dev/null
+++ b/core/res/res/raw/find_element_android.js
@@ -0,0 +1,26 @@
+function(){return function(){var i=this;
+function j(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if(b==
+"function"&&typeof a.call=="undefined")return"object";return b}function aa(a){var b=j(a);return b=="array"||b=="object"&&typeof a.length=="number"}function k(a){return typeof a=="string"}function l(a){return j(a)=="function"}function ba(a){a=j(a);return a=="object"||a=="array"||a=="function"}var ca=Date.now||function(){return+new Date};function m(a,b){function c(){}c.prototype=b.prototype;a.m=b.prototype;a.prototype=new c};function n(a){this.stack=Error().stack||"";if(a)this.message=String(a)}m(n,Error);n.prototype.name="CustomError";function da(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function ea(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function fa(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function o(a,b){n.call(this,b);this.code=a;this.name=p[a]||p[13]}m(o,n);var p,ga={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},ha={};for(var ia in ga)ha[ga[ia]]=ia;p=ha;
+o.prototype.toString=function(){return"["+this.name+"] "+this.message};function ja(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a}function q(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}function r(a,b){if(a<b)return-1;else if(a>b)return 1;return 0}var ka={};function la(a){return ka[a]||(ka[a]=String(a).replace(/\-([a-z])/g,function(b,c){return c.toUpperCase()}))};function s(a,b){b.unshift(a);n.call(this,ja.apply(null,b));b.shift();this.n=a}m(s,n);s.prototype.name="AssertionError";function t(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new s(""+d,e||[]);}return a};var u=Array.prototype,ma=u.indexOf?function(a,b,c){t(a.length!=null);return u.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(k(a)){if(!k(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},na=u.forEach?function(a,b,c){t(a.length!=null);u.forEach.call(a,b,c)}:function(a,b,c){var d=a.length,e=k(a)?a.split(""):a;for(var f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},v=u.filter?function(a,b,c){t(a.length!=null);return u.filter.call(a,
+b,c)}:function(a,b,c){var d=a.length,e=[],f=0,g=k(a)?a.split(""):a;for(var h=0;h<d;h++)if(h in g){var G=g[h];if(b.call(c,G,h,a))e[f++]=G}return e},w=u.map?function(a,b,c){t(a.length!=null);return u.map.call(a,b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=k(a)?a.split(""):a;for(var g=0;g<d;g++)if(g in f)e[g]=b.call(c,f[g],g,a);return e},oa=u.some?function(a,b,c){t(a.length!=null);return u.some.call(a,b,c)}:function(a,b,c){var d=a.length,e=k(a)?a.split(""):a;for(var f=0;f<d;f++)if(f in e&&b.call(c,
+e[f],f,a))return true;return false};function x(a,b,c){a:{var d=a.length,e=k(a)?a.split(""):a;for(var f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a)){b=f;break a}b=-1}return b<0?null:k(a)?a.charAt(b):a[b]};var A=true,pa,qa="",B;if(A)B=/WebKit\/(\S+)/;if(B){var ra=B.exec(i.navigator?i.navigator.userAgent:null);qa=ra?ra[1]:""}pa=qa;var sa={};var ta;function C(a,b){this.width=a;this.height=b}C.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};function D(a){return a?new E(F(a)):ta||(ta=new E)}function H(a,b){if(a.contains&&b.nodeType==1)return a==b||a.contains(b);if(typeof a.compareDocumentPosition!="undefined")return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}function F(a){return a.nodeType==9?a:a.ownerDocument||a.document}function ua(a,b){var c=[];return va(a,b,c,true)?c[0]:undefined}
+function va(a,b,c,d){if(a!=null){var e=0;for(var f;f=a.childNodes[e];e++){if(b(f)){c.push(f);if(d)return true}if(va(f,b,c,d))return true}}return false}function wa(a,b,c,d){if(!c)a=a.parentNode;c=d==null;for(var e=0;a&&(c||e<=d);){if(b(a))return a;a=a.parentNode;e++}return null}function E(a){this.g=a||i.document||document}
+function I(a,b,c,d){a=d||a.g;b=b&&b!="*"?b.toUpperCase():"";if(d=a.querySelectorAll){if(d=a.querySelector){if(!(d=!A)){if(!(d=document.compatMode=="CSS1Compat")){if(!(d=sa["528"])){d=0;var e=q(String(pa)).split("."),f=q(String("528")).split("."),g=Math.max(e.length,f.length);for(var h=0;d==0&&h<g;h++){var G=e[h]||"",Oa=f[h]||"",Pa=RegExp("(\\d*)(\\D*)","g"),Qa=RegExp("(\\d*)(\\D*)","g");do{var y=Pa.exec(G)||["","",""],z=Qa.exec(Oa)||["","",""];if(y[0].length==0&&z[0].length==0)break;d=r(y[1].length==
+0?0:parseInt(y[1],10),z[1].length==0?0:parseInt(z[1],10))||r(y[2].length==0,z[2].length==0)||r(y[2],z[2])}while(d==0)}d=sa["528"]=d>=0}d=d}d=d}d=d}d=d}if(d&&(b||c))c=a.querySelectorAll(b+(c?"."+c:""));else if(c&&a.getElementsByClassName){a=a.getElementsByClassName(c);if(b){d={};f=e=0;for(;g=a[f];f++)if(b==g.nodeName)d[e++]=g;d.length=e;c=d}else c=a}else{a=a.getElementsByTagName(b||"*");if(c){d={};e=0;for(f=0;g=a[f];f++){b=g.className;if(typeof b.split=="function"&&ma(b.split(/\s+/),c)>=0)d[e++]=g}d.length=
+e;c=d}else c=a}return c}E.prototype.contains=H;function xa(){}
+function J(a,b,c){switch(typeof b){case "string":ya(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(j(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);J(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);ya(a,e,c);c.push(":");J(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var K={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},za=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function ya(a,b,c){c.push('"',b.replace(za,function(d){if(d in K)return K[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return K[d]=f+e.toString(16)}),'"')};function L(a){switch(j(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return w(a,L);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=Aa(a);return b}if(aa(a))return w(a,L);a=da(a,function(c,d){return typeof d=="number"||k(d)});return ea(a,L);default:return null}}
+function M(a,b){if(j(a)=="array")return w(a,function(c){return M(c,b)});else if(ba(a))return"ELEMENT"in a?Ba(a.ELEMENT,b):ea(a,function(c){return M(c,b)});return a}function Ca(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.l=ca()}return b}function Aa(a){var b=Ca(a.ownerDocument),c=fa(b,function(d){return d==a});if(!c){c=":wdc:"+b.l++;b[c]=a}return c}
+function Ba(a,b){a=decodeURIComponent(a);var c=b||document,d=Ca(c);if(!(a in d))throw new o(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new o(10,"Element is no longer attached to the DOM");};var Da=window;var N={};N.b=function(a,b){if(!a)throw Error("No class name specified");a=q(a);if(a.split(/\s+/).length>1)throw Error("Compound class names not permitted");var c=I(D(b),"*",a,b);return c.length?c[0]:null};N.e=function(a,b){if(!a)throw Error("No class name specified");a=q(a);if(a.split(/\s+/).length>1)throw Error("Compound class names not permitted");return I(D(b),"*",a,b)};var O={};O.b=function(a,b){if(!l(b.querySelector)&&0)throw Error("CSS selection is not supported");if(!a)throw Error("No selector specified");if(a.split(/,/).length>1)throw Error("Compound selectors not permitted");a=q(a);var c=b.querySelector(a);return c&&c.nodeType==1?c:null};O.e=function(a,b){if(!l(b.querySelectorAll)&&0)throw Error("CSS selection is not supported");if(!a)throw Error("No selector specified");if(a.split(/,/).length>1)throw Error("Compound selectors not permitted");a=q(a);return b.querySelectorAll(a)};function Ea(a,b){if(typeof a.selectNodes!="undefined"){var c=F(a);typeof c.setProperty!="undefined"&&c.setProperty("SelectionLanguage","XPath");return a.selectNodes(b)}else if(document.implementation.hasFeature("XPath","3.0")){c=F(a);var d=c.createNSResolver(c.documentElement);c=c.evaluate(b,a,d,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);d=[];var e=c.snapshotLength;for(var f=0;f<e;f++)d.push(c.snapshotItem(f));return d}else return[]};var P={};P.b=function(a,b){try{var c;if(typeof b.selectSingleNode!="undefined"){var d=F(b);typeof d.setProperty!="undefined"&&d.setProperty("SelectionLanguage","XPath");c=b.selectSingleNode(a)}else if(document.implementation.hasFeature("XPath","3.0")){d=F(b);var e=d.createNSResolver(d.documentElement);c=d.evaluate(a,b,e,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}else c=null}catch(f){return null}if(!c)return null;if(c.nodeType!=1)throw Error("Returned node is not an element: "+a);return c};
+P.e=function(a,b){var c=Ea(b,a);na(c,function(d){if(d.nodeType!=1)throw Error("Returned nodes must be elements: "+a);});return c};var Fa="StopIteration"in i?i.StopIteration:Error("StopIteration");function Ga(){}Ga.prototype.next=function(){throw Fa;};function Q(a,b,c,d,e){this.a=!!b;a&&R(this,a,d);this.f=e!=undefined?e:this.d||0;if(this.a)this.f*=-1;this.k=!c}m(Q,Ga);Q.prototype.c=null;Q.prototype.d=0;Q.prototype.j=false;function R(a,b,c,d){if(a.c=b)a.d=typeof c=="number"?c:a.c.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.f=d}
+Q.prototype.next=function(){var a;if(this.j){if(!this.c||this.k&&this.f==0)throw Fa;a=this.c;var b=this.a?-1:1;if(this.d==b){var c=this.a?a.lastChild:a.firstChild;c?R(this,c):R(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?R(this,c):R(this,a.parentNode,b*-1);this.f+=this.d*(this.a?-1:1)}else this.j=true;a=this.c;if(!this.c)throw Fa;return a};
+Q.prototype.splice=function(){var a=this.c,b=this.a?1:-1;if(this.d==b){this.d=b*-1;this.f+=this.d*(this.a?-1:1)}this.a=!this.a;Q.prototype.next.call(this);this.a=!this.a;b=aa(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function Ha(a,b,c,d){Q.call(this,a,b,c,null,d)}m(Ha,Q);Ha.prototype.next=function(){do Ha.m.next.call(this);while(this.d==-1);return this.c};function Ia(a,b){var c=F(a);if(c.defaultView&&c.defaultView.getComputedStyle)if(c=c.defaultView.getComputedStyle(a,null))return c[b]||c.getPropertyValue(b);return""};function S(a,b){return!!a&&a.nodeType==1&&(!b||a.tagName.toUpperCase()==b)}
+var Ja=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking","selected","spellcheck","truespeed","willvalidate"];
+function T(a,b){if(8==a.nodeType)return null;b=b.toLowerCase();if(b=="style"){var c=q(a.style.cssText).toLowerCase();return c.charAt(c.length-1)==";"?c:c+";"}c=a.getAttributeNode(b);if(!c)return null;if(ma(Ja,b)>=0)return"true";return c.specified?c.value:null}function U(a){for(a=a.parentNode;a&&a.nodeType!=1&&a.nodeType!=9&&a.nodeType!=11;)a=a.parentNode;return S(a)?a:null}function V(a,b){b=la(String(b));return Ia(a,b)||Ka(a,b)}
+function Ka(a,b){var c=(a.currentStyle||a.style)[b];if(c!="inherit")return c!==undefined?c:null;return(c=U(a))?Ka(c,b):null}
+function La(a){if(l(a.getBBox))return a.getBBox();var b;if((Ia(a,"display")||(a.currentStyle?a.currentStyle.display:null)||a.style.display)!="none")b=new C(a.offsetWidth,a.offsetHeight);else{b=a.style;var c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";var f;f=a.offsetWidth;a=a.offsetHeight;b.display=c;b.position=e;b.visibility=d;b=new C(f,a)}return b}
+function W(a,b){function c(f){if(V(f,"display")=="none")return false;f=U(f);return!f||c(f)}function d(f){var g=La(f);if(g.height>0&&g.width>0)return true;if(f.innerText||f.textContent)if(Ma.test(f.innerText||f.textContent))return true;return A&&oa(f.childNodes,function(h){return S(h)&&d(h)})}if(!S(a))throw Error("Argument to isShown must be of type Element");if(S(a,"TITLE"))return(F(a)?F(a).parentWindow||F(a).defaultView:window)==Da;if(S(a,"OPTION")||S(a,"OPTGROUP")){var e=wa(a,function(f){return S(f,
+"SELECT")});return!!e&&W(e)}if(S(a,"MAP")){if(!a.name)return false;e=F(a);e=e.evaluate?P.b('/descendant::*[@usemap = "#'+a.name+'"]',e):ua(e,function(f){return S(f)&&T(f,"usemap")=="#"+a.name});return!!e&&W(e)}if(S(a,"AREA")){e=wa(a,function(f){return S(f,"MAP")});return!!e&&W(e)}if(S(a,"INPUT")&&a.type.toLowerCase()=="hidden")return false;if(V(a,"visibility")=="hidden")return false;if(!c(a))return false;if(!b&&Na(a)==0)return false;if(!d(a))return false;return true}
+function Ra(a){var b=[""];Sa(a,b);b=w(b,q);return q(b.join("\n"))}function Sa(a,b){if(S(a,"BR"))b.push("");else{var c=Ta(a);c&&b[b.length-1]&&b.push("");na(a.childNodes,function(d){if(d.nodeType==3){var e=U(d);if(e){W(e);if(e&&W(e)){d=d.nodeValue.replace(Ua," ");e=b.pop();var f=e.length-1;if(f>=0&&e.indexOf(" ",f)==f&&d.lastIndexOf(" ",0)==0)d=d.substr(1);b.push(e+d)}}}else S(d)&&Sa(d,b)});c&&b[b.length-1]&&b.push("")}}function Ta(a){a=V(a,"display");return a=="block"||a=="inline-block"}
+var Va="[\\s\\xa0"+String.fromCharCode(160)+"]+",Ua=RegExp(Va,"g"),Ma=RegExp("^"+Va+"$");function Na(a){var b=1,c=V(a,"opacity");if(c)b=Number(c);if(a=U(a))b*=Na(a);return b};var Wa={};Wa.b=function(a,b){var c=D(b),d=k(a)?c.g.getElementById(a):a;if(!d)return null;if(T(d,"id")==a&&H(b,d))return d;c=I(c,"*");return x(c,function(e){return T(e,"id")==a&&H(b,e)})};Wa.e=function(a,b){var c=I(D(b),"*",null,b);return v(c,function(d){return T(d,"id")==a})};var X={},Xa={};X.i=function(a,b,c){b=I(D(b),"A",null,b);return x(b,function(d){d=Ra(d);return c&&d.indexOf(a)!=-1||d==a})};X.h=function(a,b,c){b=I(D(b),"A",null,b);return v(b,function(d){d=Ra(d);return c&&d.indexOf(a)!=-1||d==a})};X.b=function(a,b){return X.i(a,b,false)};X.e=function(a,b){return X.h(a,b,false)};Xa.b=function(a,b){return X.i(a,b,true)};Xa.e=function(a,b){return X.h(a,b,true)};var Ya={};Ya.b=function(a,b){var c=I(D(b),"*",null,b);return x(c,function(d){return T(d,"name")==a})};Ya.e=function(a,b){var c=I(D(b),"*",null,b);return v(c,function(d){return T(d,"name")==a})};var Za={};Za.b=function(a,b){return I(D(b),a,null,b)[0]||null};Za.e=function(a,b){return I(D(b),a,null,b)};var $a={className:N,css:O,id:Wa,linkText:X,name:Ya,partialLinkText:Xa,tagName:Za,xpath:P};function ab(a,b){var c;a:{for(c in a){c=c;break a}c=void 0}if(c){var d=$a[c];if(d&&l(d.b))return d.b(a[c],b||F(Da))}throw Error("Unsupported locator strategy: "+c);};function bb(a,b,c){var d={};d[a]=b;a=ab;c=[d,c];var e;try{if(k(a))a=new Function(a);var f=M(c),g=a.apply(null,f);e={status:0,value:L(g)}}catch(h){e={status:"code"in h?h.code:13,value:{message:h.message}}}f=[];J(new xa,e,f);return f.join("")}var Y="_".split("."),Z=i;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&bb!==undefined)Z[$]=bb;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/find_elements_android.js b/core/res/res/raw/find_elements_android.js
new file mode 100644
index 0000000..796da58
--- /dev/null
+++ b/core/res/res/raw/find_elements_android.js
@@ -0,0 +1,26 @@
+function(){return function(){var i=this;
+function j(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if(b==
+"function"&&typeof a.call=="undefined")return"object";return b}function aa(a){var b=j(a);return b=="array"||b=="object"&&typeof a.length=="number"}function k(a){return typeof a=="string"}function l(a){return j(a)=="function"}function ba(a){a=j(a);return a=="object"||a=="array"||a=="function"}var ca=Date.now||function(){return+new Date};function m(a,b){function c(){}c.prototype=b.prototype;a.m=b.prototype;a.prototype=new c};function n(a){this.stack=Error().stack||"";if(a)this.message=String(a)}m(n,Error);n.prototype.name="CustomError";function da(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function ea(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function fa(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function o(a,b){n.call(this,b);this.code=a;this.name=p[a]||p[13]}m(o,n);var p,ga={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},ha={};for(var ia in ga)ha[ga[ia]]=ia;p=ha;
+o.prototype.toString=function(){return"["+this.name+"] "+this.message};function ja(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a}function q(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}function r(a,b){if(a<b)return-1;else if(a>b)return 1;return 0}var ka={};function la(a){return ka[a]||(ka[a]=String(a).replace(/\-([a-z])/g,function(b,c){return c.toUpperCase()}))};function s(a,b){b.unshift(a);n.call(this,ja.apply(null,b));b.shift();this.n=a}m(s,n);s.prototype.name="AssertionError";function t(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new s(""+d,e||[]);}return a};var u=Array.prototype,ma=u.indexOf?function(a,b,c){t(a.length!=null);return u.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(k(a)){if(!k(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},na=u.forEach?function(a,b,c){t(a.length!=null);u.forEach.call(a,b,c)}:function(a,b,c){var d=a.length,e=k(a)?a.split(""):a;for(var f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},v=u.filter?function(a,b,c){t(a.length!=null);return u.filter.call(a,
+b,c)}:function(a,b,c){var d=a.length,e=[],f=0,g=k(a)?a.split(""):a;for(var h=0;h<d;h++)if(h in g){var G=g[h];if(b.call(c,G,h,a))e[f++]=G}return e},w=u.map?function(a,b,c){t(a.length!=null);return u.map.call(a,b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=k(a)?a.split(""):a;for(var g=0;g<d;g++)if(g in f)e[g]=b.call(c,f[g],g,a);return e},oa=u.some?function(a,b,c){t(a.length!=null);return u.some.call(a,b,c)}:function(a,b,c){var d=a.length,e=k(a)?a.split(""):a;for(var f=0;f<d;f++)if(f in e&&b.call(c,
+e[f],f,a))return true;return false};function x(a,b,c){a:{var d=a.length,e=k(a)?a.split(""):a;for(var f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a)){b=f;break a}b=-1}return b<0?null:k(a)?a.charAt(b):a[b]};var A=true,pa,qa="",B;if(A)B=/WebKit\/(\S+)/;if(B){var ra=B.exec(i.navigator?i.navigator.userAgent:null);qa=ra?ra[1]:""}pa=qa;var sa={};var ta;function C(a,b){this.width=a;this.height=b}C.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};function D(a){return a?new E(F(a)):ta||(ta=new E)}function H(a,b){if(a.contains&&b.nodeType==1)return a==b||a.contains(b);if(typeof a.compareDocumentPosition!="undefined")return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}function F(a){return a.nodeType==9?a:a.ownerDocument||a.document}function ua(a,b){var c=[];return va(a,b,c,true)?c[0]:undefined}
+function va(a,b,c,d){if(a!=null){var e=0;for(var f;f=a.childNodes[e];e++){if(b(f)){c.push(f);if(d)return true}if(va(f,b,c,d))return true}}return false}function wa(a,b,c,d){if(!c)a=a.parentNode;c=d==null;for(var e=0;a&&(c||e<=d);){if(b(a))return a;a=a.parentNode;e++}return null}function E(a){this.g=a||i.document||document}
+function I(a,b,c,d){a=d||a.g;b=b&&b!="*"?b.toUpperCase():"";if(d=a.querySelectorAll){if(d=a.querySelector){if(!(d=!A)){if(!(d=document.compatMode=="CSS1Compat")){if(!(d=sa["528"])){d=0;var e=q(String(pa)).split("."),f=q(String("528")).split("."),g=Math.max(e.length,f.length);for(var h=0;d==0&&h<g;h++){var G=e[h]||"",Oa=f[h]||"",Pa=RegExp("(\\d*)(\\D*)","g"),Qa=RegExp("(\\d*)(\\D*)","g");do{var y=Pa.exec(G)||["","",""],z=Qa.exec(Oa)||["","",""];if(y[0].length==0&&z[0].length==0)break;d=r(y[1].length==
+0?0:parseInt(y[1],10),z[1].length==0?0:parseInt(z[1],10))||r(y[2].length==0,z[2].length==0)||r(y[2],z[2])}while(d==0)}d=sa["528"]=d>=0}d=d}d=d}d=d}d=d}if(d&&(b||c))c=a.querySelectorAll(b+(c?"."+c:""));else if(c&&a.getElementsByClassName){a=a.getElementsByClassName(c);if(b){d={};f=e=0;for(;g=a[f];f++)if(b==g.nodeName)d[e++]=g;d.length=e;c=d}else c=a}else{a=a.getElementsByTagName(b||"*");if(c){d={};e=0;for(f=0;g=a[f];f++){b=g.className;if(typeof b.split=="function"&&ma(b.split(/\s+/),c)>=0)d[e++]=g}d.length=
+e;c=d}else c=a}return c}E.prototype.contains=H;function xa(){}
+function J(a,b,c){switch(typeof b){case "string":ya(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(j(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);J(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);ya(a,e,c);c.push(":");J(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var K={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},za=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function ya(a,b,c){c.push('"',b.replace(za,function(d){if(d in K)return K[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return K[d]=f+e.toString(16)}),'"')};function L(a){switch(j(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return w(a,L);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=Aa(a);return b}if(aa(a))return w(a,L);a=da(a,function(c,d){return typeof d=="number"||k(d)});return ea(a,L);default:return null}}
+function M(a,b){if(j(a)=="array")return w(a,function(c){return M(c,b)});else if(ba(a))return"ELEMENT"in a?Ba(a.ELEMENT,b):ea(a,function(c){return M(c,b)});return a}function Ca(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.l=ca()}return b}function Aa(a){var b=Ca(a.ownerDocument),c=fa(b,function(d){return d==a});if(!c){c=":wdc:"+b.l++;b[c]=a}return c}
+function Ba(a,b){a=decodeURIComponent(a);var c=b||document,d=Ca(c);if(!(a in d))throw new o(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new o(10,"Element is no longer attached to the DOM");};var Da=window;var N={};N.d=function(a,b){if(!a)throw Error("No class name specified");a=q(a);if(a.split(/\s+/).length>1)throw Error("Compound class names not permitted");var c=I(D(b),"*",a,b);return c.length?c[0]:null};N.b=function(a,b){if(!a)throw Error("No class name specified");a=q(a);if(a.split(/\s+/).length>1)throw Error("Compound class names not permitted");return I(D(b),"*",a,b)};var O={};O.d=function(a,b){if(!l(b.querySelector)&&0)throw Error("CSS selection is not supported");if(!a)throw Error("No selector specified");if(a.split(/,/).length>1)throw Error("Compound selectors not permitted");a=q(a);var c=b.querySelector(a);return c&&c.nodeType==1?c:null};O.b=function(a,b){if(!l(b.querySelectorAll)&&0)throw Error("CSS selection is not supported");if(!a)throw Error("No selector specified");if(a.split(/,/).length>1)throw Error("Compound selectors not permitted");a=q(a);return b.querySelectorAll(a)};function Ea(a,b){if(typeof a.selectNodes!="undefined"){var c=F(a);typeof c.setProperty!="undefined"&&c.setProperty("SelectionLanguage","XPath");return a.selectNodes(b)}else if(document.implementation.hasFeature("XPath","3.0")){c=F(a);var d=c.createNSResolver(c.documentElement);c=c.evaluate(b,a,d,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);d=[];var e=c.snapshotLength;for(var f=0;f<e;f++)d.push(c.snapshotItem(f));return d}else return[]};var P={};P.d=function(a,b){try{var c;if(typeof b.selectSingleNode!="undefined"){var d=F(b);typeof d.setProperty!="undefined"&&d.setProperty("SelectionLanguage","XPath");c=b.selectSingleNode(a)}else if(document.implementation.hasFeature("XPath","3.0")){d=F(b);var e=d.createNSResolver(d.documentElement);c=d.evaluate(a,b,e,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}else c=null}catch(f){return null}if(!c)return null;if(c.nodeType!=1)throw Error("Returned node is not an element: "+a);return c};
+P.b=function(a,b){var c=Ea(b,a);na(c,function(d){if(d.nodeType!=1)throw Error("Returned nodes must be elements: "+a);});return c};var Fa="StopIteration"in i?i.StopIteration:Error("StopIteration");function Ga(){}Ga.prototype.next=function(){throw Fa;};function Q(a,b,c,d,e){this.a=!!b;a&&R(this,a,d);this.f=e!=undefined?e:this.e||0;if(this.a)this.f*=-1;this.k=!c}m(Q,Ga);Q.prototype.c=null;Q.prototype.e=0;Q.prototype.j=false;function R(a,b,c,d){if(a.c=b)a.e=typeof c=="number"?c:a.c.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.f=d}
+Q.prototype.next=function(){var a;if(this.j){if(!this.c||this.k&&this.f==0)throw Fa;a=this.c;var b=this.a?-1:1;if(this.e==b){var c=this.a?a.lastChild:a.firstChild;c?R(this,c):R(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?R(this,c):R(this,a.parentNode,b*-1);this.f+=this.e*(this.a?-1:1)}else this.j=true;a=this.c;if(!this.c)throw Fa;return a};
+Q.prototype.splice=function(){var a=this.c,b=this.a?1:-1;if(this.e==b){this.e=b*-1;this.f+=this.e*(this.a?-1:1)}this.a=!this.a;Q.prototype.next.call(this);this.a=!this.a;b=aa(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function Ha(a,b,c,d){Q.call(this,a,b,c,null,d)}m(Ha,Q);Ha.prototype.next=function(){do Ha.m.next.call(this);while(this.e==-1);return this.c};function Ia(a,b){var c=F(a);if(c.defaultView&&c.defaultView.getComputedStyle)if(c=c.defaultView.getComputedStyle(a,null))return c[b]||c.getPropertyValue(b);return""};function S(a,b){return!!a&&a.nodeType==1&&(!b||a.tagName.toUpperCase()==b)}
+var Ja=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking","selected","spellcheck","truespeed","willvalidate"];
+function T(a,b){if(8==a.nodeType)return null;b=b.toLowerCase();if(b=="style"){var c=q(a.style.cssText).toLowerCase();return c.charAt(c.length-1)==";"?c:c+";"}c=a.getAttributeNode(b);if(!c)return null;if(ma(Ja,b)>=0)return"true";return c.specified?c.value:null}function U(a){for(a=a.parentNode;a&&a.nodeType!=1&&a.nodeType!=9&&a.nodeType!=11;)a=a.parentNode;return S(a)?a:null}function V(a,b){b=la(String(b));return Ia(a,b)||Ka(a,b)}
+function Ka(a,b){var c=(a.currentStyle||a.style)[b];if(c!="inherit")return c!==undefined?c:null;return(c=U(a))?Ka(c,b):null}
+function La(a){if(l(a.getBBox))return a.getBBox();var b;if((Ia(a,"display")||(a.currentStyle?a.currentStyle.display:null)||a.style.display)!="none")b=new C(a.offsetWidth,a.offsetHeight);else{b=a.style;var c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";var f;f=a.offsetWidth;a=a.offsetHeight;b.display=c;b.position=e;b.visibility=d;b=new C(f,a)}return b}
+function W(a,b){function c(f){if(V(f,"display")=="none")return false;f=U(f);return!f||c(f)}function d(f){var g=La(f);if(g.height>0&&g.width>0)return true;if(f.innerText||f.textContent)if(Ma.test(f.innerText||f.textContent))return true;return A&&oa(f.childNodes,function(h){return S(h)&&d(h)})}if(!S(a))throw Error("Argument to isShown must be of type Element");if(S(a,"TITLE"))return(F(a)?F(a).parentWindow||F(a).defaultView:window)==Da;if(S(a,"OPTION")||S(a,"OPTGROUP")){var e=wa(a,function(f){return S(f,
+"SELECT")});return!!e&&W(e)}if(S(a,"MAP")){if(!a.name)return false;e=F(a);e=e.evaluate?P.d('/descendant::*[@usemap = "#'+a.name+'"]',e):ua(e,function(f){return S(f)&&T(f,"usemap")=="#"+a.name});return!!e&&W(e)}if(S(a,"AREA")){e=wa(a,function(f){return S(f,"MAP")});return!!e&&W(e)}if(S(a,"INPUT")&&a.type.toLowerCase()=="hidden")return false;if(V(a,"visibility")=="hidden")return false;if(!c(a))return false;if(!b&&Na(a)==0)return false;if(!d(a))return false;return true}
+function Ra(a){var b=[""];Sa(a,b);b=w(b,q);return q(b.join("\n"))}function Sa(a,b){if(S(a,"BR"))b.push("");else{var c=Ta(a);c&&b[b.length-1]&&b.push("");na(a.childNodes,function(d){if(d.nodeType==3){var e=U(d);if(e){W(e);if(e&&W(e)){d=d.nodeValue.replace(Ua," ");e=b.pop();var f=e.length-1;if(f>=0&&e.indexOf(" ",f)==f&&d.lastIndexOf(" ",0)==0)d=d.substr(1);b.push(e+d)}}}else S(d)&&Sa(d,b)});c&&b[b.length-1]&&b.push("")}}function Ta(a){a=V(a,"display");return a=="block"||a=="inline-block"}
+var Va="[\\s\\xa0"+String.fromCharCode(160)+"]+",Ua=RegExp(Va,"g"),Ma=RegExp("^"+Va+"$");function Na(a){var b=1,c=V(a,"opacity");if(c)b=Number(c);if(a=U(a))b*=Na(a);return b};var Wa={};Wa.d=function(a,b){var c=D(b),d=k(a)?c.g.getElementById(a):a;if(!d)return null;if(T(d,"id")==a&&H(b,d))return d;c=I(c,"*");return x(c,function(e){return T(e,"id")==a&&H(b,e)})};Wa.b=function(a,b){var c=I(D(b),"*",null,b);return v(c,function(d){return T(d,"id")==a})};var X={},Xa={};X.i=function(a,b,c){b=I(D(b),"A",null,b);return x(b,function(d){d=Ra(d);return c&&d.indexOf(a)!=-1||d==a})};X.h=function(a,b,c){b=I(D(b),"A",null,b);return v(b,function(d){d=Ra(d);return c&&d.indexOf(a)!=-1||d==a})};X.d=function(a,b){return X.i(a,b,false)};X.b=function(a,b){return X.h(a,b,false)};Xa.d=function(a,b){return X.i(a,b,true)};Xa.b=function(a,b){return X.h(a,b,true)};var Ya={};Ya.d=function(a,b){var c=I(D(b),"*",null,b);return x(c,function(d){return T(d,"name")==a})};Ya.b=function(a,b){var c=I(D(b),"*",null,b);return v(c,function(d){return T(d,"name")==a})};var Za={};Za.d=function(a,b){return I(D(b),a,null,b)[0]||null};Za.b=function(a,b){return I(D(b),a,null,b)};var $a={className:N,css:O,id:Wa,linkText:X,name:Ya,partialLinkText:Xa,tagName:Za,xpath:P};function ab(a,b){var c;a:{for(c in a){c=c;break a}c=void 0}if(c){var d=$a[c];if(d&&l(d.b))return d.b(a[c],b||F(Da))}throw Error("Unsupported locator strategy: "+c);};function bb(a,b,c){var d={};d[a]=b;a=ab;c=[d,c];var e;try{if(k(a))a=new Function(a);var f=M(c),g=a.apply(null,f);e={status:0,value:L(g)}}catch(h){e={status:"code"in h?h.code:13,value:{message:h.message}}}f=[];J(new xa,e,f);return f.join("")}var Y="_".split("."),Z=i;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&bb!==undefined)Z[$]=bb;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/get_attribute_value_android.js b/core/res/res/raw/get_attribute_value_android.js
new file mode 100644
index 0000000..e96a868
--- /dev/null
+++ b/core/res/res/raw/get_attribute_value_android.js
@@ -0,0 +1,11 @@
+function(){return function(){function g(a){var c=typeof a;if(c=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return c;var b=Object.prototype.toString.call(a);if(b=="[object Window]")return"object";if(b=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(b=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(c=="function"&&typeof a.call=="undefined")return"object";return c}function i(a){var c=g(a);return c=="array"||c=="object"&&typeof a.length=="number"}function j(a){return typeof a=="string"}function k(a){a=g(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var l=Date.now||function(){return+new Date};function m(a,c){function b(){}b.prototype=c.prototype;a.h=c.prototype;a.prototype=new b};function n(a){this.stack=Error().stack||"";if(a)this.message=String(a)}m(n,Error);n.prototype.name="CustomError";function o(a,c,b){var d={};for(var e in a)if(c.call(b,a[e],e,a))d[e]=a[e];return d}function p(a,c,b){var d={};for(var e in a)d[e]=c.call(b,a[e],e,a);return d}function q(a,c,b){for(var d in a)if(c.call(b,a[d],d,a))return d};function r(a,c){n.call(this,c);this.code=a;this.name=s[a]||s[13]}m(r,n);var s,t={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},u={};for(var v in t)u[t[v]]=v;s=u;
+r.prototype.toString=function(){return"["+this.name+"] "+this.message};function w(a){for(var c=1;c<arguments.length;c++){var b=String(arguments[c]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,b)}return a};function x(a,c){c.unshift(a);n.call(this,w.apply(null,c));c.shift();this.i=a}m(x,n);x.prototype.name="AssertionError";function y(a,c){if(!a){var b=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(c){d+=": "+c;var e=b}throw new x(""+d,e||[]);}return a};var z=Array.prototype,A=z.indexOf?function(a,c,b){y(a.length!=null);return z.indexOf.call(a,c,b)}:function(a,c,b){b=b==null?0:b<0?Math.max(0,a.length+b):b;if(j(a)){if(!j(c)||c.length!=1)return-1;return a.indexOf(c,b)}for(b=b;b<a.length;b++)if(b in a&&a[b]===c)return b;return-1},C=z.map?function(a,c,b){y(a.length!=null);return z.map.call(a,c,b)}:function(a,c,b){var d=a.length,e=Array(d),f=j(a)?a.split(""):a;for(var h=0;h<d;h++)if(h in f)e[h]=c.call(b,f[h],h,a);return e};var D="",E;if(E=/WebKit\/(\S+)/){var F=E.exec(this.navigator?this.navigator.userAgent:null);D=F?F[1]:""};var G="StopIteration"in this?this.StopIteration:Error("StopIteration");function H(){}H.prototype.next=function(){throw G;};function I(a,c,b,d,e){this.a=!!c;a&&J(this,a,d);this.d=e!=undefined?e:this.c||0;if(this.a)this.d*=-1;this.f=!b}m(I,H);I.prototype.b=null;I.prototype.c=0;I.prototype.e=false;function J(a,c,b,d){if(a.b=c)a.c=typeof b=="number"?b:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+I.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&this.d==0)throw G;a=this.b;var c=this.a?-1:1;if(this.c==c){var b=this.a?a.lastChild:a.firstChild;b?J(this,b):J(this,a,c*-1)}else(b=this.a?a.previousSibling:a.nextSibling)?J(this,b):J(this,a.parentNode,c*-1);this.d+=this.c*(this.a?-1:1)}else this.e=true;a=this.b;if(!this.b)throw G;return a};
+I.prototype.splice=function(){var a=this.b,c=this.a?1:-1;if(this.c==c){this.c=c*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;I.prototype.next.call(this);this.a=!this.a;c=i(arguments[0])?arguments[0]:arguments;for(var b=c.length-1;b>=0;b--)a.parentNode&&a.parentNode.insertBefore(c[b],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function K(a,c,b,d){I.call(this,a,c,b,null,d)}m(K,I);K.prototype.next=function(){do K.h.next.call(this);while(this.c==-1);return this.b};var L=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking","selected","spellcheck","truespeed","willvalidate"];
+function M(a,c){if(8==a.nodeType)return null;c=c.toLowerCase();if(c=="style"){var b=a.style.cssText.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").toLowerCase();return b.charAt(b.length-1)==";"?b:b+";"}b=a.getAttributeNode(c);if(!b)return null;if(A(L,c)>=0)return"true";return b.specified?b.value:null}String.fromCharCode(160);function N(){}
+function O(a,c,b){switch(typeof c){case "string":P(a,c,b);break;case "number":b.push(isFinite(c)&&!isNaN(c)?c:"null");break;case "boolean":b.push(c);break;case "undefined":b.push("null");break;case "object":if(c==null){b.push("null");break}if(g(c)=="array"){var d=c.length;b.push("[");var e="";for(var f=0;f<d;f++){b.push(e);O(a,c[f],b);e=","}b.push("]");break}b.push("{");d="";for(e in c)if(Object.prototype.hasOwnProperty.call(c,e)){f=c[e];if(typeof f!="function"){b.push(d);P(a,e,b);b.push(":");O(a,
+f,b);d=","}}b.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof c);}}var Q={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},R=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function P(a,c,b){b.push('"',c.replace(R,function(d){if(d in Q)return Q[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return Q[d]=f+e.toString(16)}),'"')};function S(a){switch(g(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return C(a,S);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var c={};c.ELEMENT=T(a);return c}if(i(a))return C(a,S);a=o(a,function(b,d){return typeof d=="number"||j(d)});return p(a,S);default:return null}}
+function U(a,c){if(g(a)=="array")return C(a,function(b){return U(b,c)});else if(k(a))return"ELEMENT"in a?V(a.ELEMENT,c):p(a,function(b){return U(b,c)});return a}function W(a){a=a||document;var c=a.$wdc_;if(!c){c=a.$wdc_={};c.g=l()}return c}function T(a){var c=W(a.ownerDocument),b=q(c,function(d){return d==a});if(!b){b=":wdc:"+c.g++;c[b]=a}return b}
+function V(a,c){a=decodeURIComponent(a);var b=c||document,d=W(b);if(!(a in d))throw new r(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==b.documentElement)return e;f=f.parentNode}delete d[a];throw new r(10,"Element is no longer attached to the DOM");};function X(a,c){var b=M,d=[a,c],e;try{if(j(b))b=new Function(b);var f=U(d),h=b.apply(null,f);e={status:0,value:S(h)}}catch(B){e={status:"code"in B?B.code:13,value:{message:B.message}}}b=[];O(new N,e,b);return b.join("")}var Y="_".split("."),Z=this;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&X!==undefined)Z[$]=X;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/get_size_android.js b/core/res/res/raw/get_size_android.js
new file mode 100644
index 0000000..78f61ee
--- /dev/null
+++ b/core/res/res/raw/get_size_android.js
@@ -0,0 +1,11 @@
+function(){return function(){function g(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(b=="function"&&typeof a.call=="undefined")return"object";return b}function h(a){var b=g(a);return b=="array"||b=="object"&&typeof a.length=="number"}function i(a){a=g(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var j=Date.now||function(){return+new Date};function l(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function m(a){this.stack=Error().stack||"";if(a)this.message=String(a)}l(m,Error);m.prototype.name="CustomError";function n(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function o(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function p(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function q(a,b){m.call(this,b);this.code=a;this.name=r[a]||r[13]}l(q,m);var r,s={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},t={};for(var u in s)t[s[u]]=u;r=t;
+q.prototype.toString=function(){return"["+this.name+"] "+this.message};function v(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a};function w(a,b){b.unshift(a);m.call(this,v.apply(null,b));b.shift();this.i=a}l(w,m);w.prototype.name="AssertionError";function x(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new w(""+d,e||[]);}return a};var y=Array.prototype,z=y.map?function(a,b,c){x(a.length!=null);return y.map.call(a,b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=typeof a=="string"?a.split(""):a;for(var k=0;k<d;k++)if(k in f)e[k]=b.call(c,f[k],k,a);return e};var A="",B;if(B=/WebKit\/(\S+)/){var C=B.exec(this.navigator?this.navigator.userAgent:null);A=C?C[1]:""};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};var E="StopIteration"in this?this.StopIteration:Error("StopIteration");function F(){}F.prototype.next=function(){throw E;};function G(a,b,c,d,e){this.a=!!b;a&&H(this,a,d);this.d=e!=undefined?e:this.c||0;if(this.a)this.d*=-1;this.f=!c}l(G,F);G.prototype.b=null;G.prototype.c=0;G.prototype.e=false;function H(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+G.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&this.d==0)throw E;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?H(this,c):H(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?H(this,c):H(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.e=true;a=this.b;if(!this.b)throw E;return a};
+G.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;G.prototype.next.call(this);this.a=!this.a;b=h(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function I(a,b,c,d){G.call(this,a,b,c,null,d)}l(I,G);I.prototype.next=function(){do I.h.next.call(this);while(this.c==-1);return this.b};function J(a){if(g(a.getBBox)=="function")return a.getBBox();var b;b:{b=a.nodeType==9?a:a.ownerDocument||a.document;if(b.defaultView&&b.defaultView.getComputedStyle)if(b=b.defaultView.getComputedStyle(a,null)){b=b.display||b.getPropertyValue("display");break b}b=""}if((b||(a.currentStyle?a.currentStyle.display:null)||a.style.display)!="none")a=new D(a.offsetWidth,a.offsetHeight);else{b=a.style;var c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";
+var f;f=a.offsetWidth;a=a.offsetHeight;b.display=c;b.position=e;b.visibility=d;a=new D(f,a)}return a}String.fromCharCode(160);function K(){}
+function L(a,b,c){switch(typeof b){case "string":M(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(g(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);L(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);M(a,e,c);c.push(":");L(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var N={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},O=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function M(a,b,c){c.push('"',b.replace(O,function(d){if(d in N)return N[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return N[d]=f+e.toString(16)}),'"')};function P(a){switch(g(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return z(a,P);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=Q(a);return b}if(h(a))return z(a,P);a=n(a,function(c,d){return typeof d=="number"||typeof d=="string"});return o(a,P);default:return null}}
+function R(a,b){if(g(a)=="array")return z(a,function(c){return R(c,b)});else if(i(a))return"ELEMENT"in a?S(a.ELEMENT,b):o(a,function(c){return R(c,b)});return a}function T(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.g=j()}return b}function Q(a){var b=T(a.ownerDocument),c=p(b,function(d){return d==a});if(!c){c=":wdc:"+b.g++;b[c]=a}return c}
+function S(a,b){a=decodeURIComponent(a);var c=b||document,d=T(c);if(!(a in d))throw new q(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new q(10,"Element is no longer attached to the DOM");};function U(a){var b=J;a=[a];var c;try{if(typeof b=="string")b=new Function(b);var d=R(a),e=b.apply(null,d);c={status:0,value:P(e)}}catch(f){c={status:"code"in f?f.code:13,value:{message:f.message}}}b=[];L(new K,c,b);return b.join("")}var V="_".split("."),W=this;!(V[0]in W)&&W.execScript&&W.execScript("var "+V[0]);for(var X;V.length&&(X=V.shift());)if(!V.length&&U!==undefined)W[X]=U;else W=W[X]?W[X]:W[X]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/get_text_android.js b/core/res/res/raw/get_text_android.js
new file mode 100644
index 0000000..75c3fed
--- /dev/null
+++ b/core/res/res/raw/get_text_android.js
@@ -0,0 +1,19 @@
+function(){return function(){function g(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(b=="function"&&typeof a.call=="undefined")return"object";return b}function i(a){var b=g(a);return b=="array"||b=="object"&&typeof a.length=="number"}function j(a){return typeof a=="string"}function aa(a){a=g(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var ba=Date.now||function(){return+new Date};function k(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function l(a){this.stack=Error().stack||"";if(a)this.message=String(a)}k(l,Error);l.prototype.name="CustomError";function ca(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function m(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function da(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function n(a,b){l.call(this,b);this.code=a;this.name=o[a]||o[13]}k(n,l);var o,p={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},q={};for(var r in p)q[p[r]]=r;o=q;
+n.prototype.toString=function(){return"["+this.name+"] "+this.message};var ea=window;function fa(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a}function s(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}var t={};function ga(a){return t[a]||(t[a]=String(a).replace(/\-([a-z])/g,function(b,c){return c.toUpperCase()}))};function u(a,b){b.unshift(a);l.call(this,fa.apply(null,b));b.shift();this.i=a}k(u,l);u.prototype.name="AssertionError";function v(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new u(""+d,e||[]);}return a};var w=Array.prototype,ha=w.indexOf?function(a,b,c){v(a.length!=null);return w.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(j(a)){if(!j(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},ia=w.forEach?function(a,b,c){v(a.length!=null);w.forEach.call(a,b,c)}:function(a,b,c){var d=a.length,e=j(a)?a.split(""):a;for(var f=0;f<d;f++)f in e&&b.call(c,e[f],f,a)},x=w.map?function(a,b,c){v(a.length!=null);return w.map.call(a,
+b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=j(a)?a.split(""):a;for(var h=0;h<d;h++)if(h in f)e[h]=b.call(c,f[h],h,a);return e},ja=w.some?function(a,b,c){v(a.length!=null);return w.some.call(a,b,c)}:function(a,b,c){var d=a.length,e=j(a)?a.split(""):a;for(var f=0;f<d;f++)if(f in e&&b.call(c,e[f],f,a))return true;return false};var y=true,ka="",z;if(y)z=/WebKit\/(\S+)/;if(z){var A=z.exec(this.navigator?this.navigator.userAgent:null);ka=A?A[1]:""};function B(a,b){this.width=a;this.height=b}B.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};B.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};function C(a){return a.nodeType==9?a:a.ownerDocument||a.document}function la(a,b){var c=[];return D(a,b,c,true)?c[0]:undefined}function D(a,b,c,d){if(a!=null){var e=0;for(var f;f=a.childNodes[e];e++){if(b(f)){c.push(f);if(d)return true}if(D(f,b,c,d))return true}}return false}function E(a,b,c,d){if(!c)a=a.parentNode;c=d==null;for(var e=0;a&&(c||e<=d);){if(b(a))return a;a=a.parentNode;e++}return null};function ma(a,b){try{var c;if(typeof b.selectSingleNode!="undefined"){var d=C(b);typeof d.setProperty!="undefined"&&d.setProperty("SelectionLanguage","XPath");c=b.selectSingleNode(a)}else if(document.implementation.hasFeature("XPath","3.0")){d=C(b);var e=d.createNSResolver(d.documentElement);c=d.evaluate(a,b,e,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}else c=null}catch(f){return null}if(!c)return null;if(c.nodeType!=1)throw Error("Returned node is not an element: "+a);return c};var F="StopIteration"in this?this.StopIteration:Error("StopIteration");function G(){}G.prototype.next=function(){throw F;};function H(a,b,c,d,e){this.a=!!b;a&&I(this,a,d);this.d=e!=undefined?e:this.c||0;if(this.a)this.d*=-1;this.f=!c}k(H,G);H.prototype.b=null;H.prototype.c=0;H.prototype.e=false;function I(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+H.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&this.d==0)throw F;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?I(this,c):I(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?I(this,c):I(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.e=true;a=this.b;if(!this.b)throw F;return a};
+H.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;H.prototype.next.call(this);this.a=!this.a;b=i(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function J(a,b,c,d){H.call(this,a,b,c,null,d)}k(J,H);J.prototype.next=function(){do J.h.next.call(this);while(this.c==-1);return this.b};function K(a,b){var c=C(a);if(c.defaultView&&c.defaultView.getComputedStyle)if(c=c.defaultView.getComputedStyle(a,null))return c[b]||c.getPropertyValue(b);return""};function L(a,b){return!!a&&a.nodeType==1&&(!b||a.tagName.toUpperCase()==b)}
+var na=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking","selected","spellcheck","truespeed","willvalidate"];
+function oa(a,b){if(8==a.nodeType)return null;b=b.toLowerCase();if(b=="style"){var c=s(a.style.cssText).toLowerCase();return c.charAt(c.length-1)==";"?c:c+";"}c=a.getAttributeNode(b);if(!c)return null;if(ha(na,b)>=0)return"true";return c.specified?c.value:null}function M(a){for(a=a.parentNode;a&&a.nodeType!=1&&a.nodeType!=9&&a.nodeType!=11;)a=a.parentNode;return L(a)?a:null}function N(a,b){b=ga(String(b));return K(a,b)||O(a,b)}
+function O(a,b){var c=(a.currentStyle||a.style)[b];if(c!="inherit")return c!==undefined?c:null;return(c=M(a))?O(c,b):null}
+function pa(a){if(g(a.getBBox)=="function")return a.getBBox();var b;if((K(a,"display")||(a.currentStyle?a.currentStyle.display:null)||a.style.display)!="none")b=new B(a.offsetWidth,a.offsetHeight);else{b=a.style;var c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";var f;f=a.offsetWidth;a=a.offsetHeight;b.display=c;b.position=e;b.visibility=d;b=new B(f,a)}return b}
+function P(a,b){function c(f){if(N(f,"display")=="none")return false;f=M(f);return!f||c(f)}function d(f){var h=pa(f);if(h.height>0&&h.width>0)return true;if(f.innerText||f.textContent)if(qa.test(f.innerText||f.textContent))return true;return y&&ja(f.childNodes,function(X){return L(X)&&d(X)})}if(!L(a))throw Error("Argument to isShown must be of type Element");if(L(a,"TITLE"))return(C(a)?C(a).parentWindow||C(a).defaultView:window)==ea;if(L(a,"OPTION")||L(a,"OPTGROUP")){var e=E(a,function(f){return L(f,
+"SELECT")});return!!e&&P(e)}if(L(a,"MAP")){if(!a.name)return false;e=C(a);e=e.evaluate?ma('/descendant::*[@usemap = "#'+a.name+'"]',e):la(e,function(f){return L(f)&&oa(f,"usemap")=="#"+a.name});return!!e&&P(e)}if(L(a,"AREA")){e=E(a,function(f){return L(f,"MAP")});return!!e&&P(e)}if(L(a,"INPUT")&&a.type.toLowerCase()=="hidden")return false;if(N(a,"visibility")=="hidden")return false;if(!c(a))return false;if(!b&&Q(a)==0)return false;if(!d(a))return false;return true}
+function ra(a){var b=[""];R(a,b);b=x(b,s);return s(b.join("\n"))}function R(a,b){if(L(a,"BR"))b.push("");else{var c=sa(a);c&&b[b.length-1]&&b.push("");ia(a.childNodes,function(d){if(d.nodeType==3){var e=M(d);if(e){P(e);if(e&&P(e)){d=d.nodeValue.replace(ta," ");e=b.pop();var f=e.length-1;if(f>=0&&e.indexOf(" ",f)==f&&d.lastIndexOf(" ",0)==0)d=d.substr(1);b.push(e+d)}}}else L(d)&&R(d,b)});c&&b[b.length-1]&&b.push("")}}function sa(a){a=N(a,"display");return a=="block"||a=="inline-block"}
+var S="[\\s\\xa0"+String.fromCharCode(160)+"]+",ta=RegExp(S,"g"),qa=RegExp("^"+S+"$");function Q(a){var b=1,c=N(a,"opacity");if(c)b=Number(c);if(a=M(a))b*=Q(a);return b};function ua(){}
+function T(a,b,c){switch(typeof b){case "string":va(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(g(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);T(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);va(a,e,c);c.push(":");T(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var U={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},wa=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function va(a,b,c){c.push('"',b.replace(wa,function(d){if(d in U)return U[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return U[d]=f+e.toString(16)}),'"')};function V(a){switch(g(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return x(a,V);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=xa(a);return b}if(i(a))return x(a,V);a=ca(a,function(c,d){return typeof d=="number"||j(d)});return m(a,V);default:return null}}
+function W(a,b){if(g(a)=="array")return x(a,function(c){return W(c,b)});else if(aa(a))return"ELEMENT"in a?ya(a.ELEMENT,b):m(a,function(c){return W(c,b)});return a}function za(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.g=ba()}return b}function xa(a){var b=za(a.ownerDocument),c=da(b,function(d){return d==a});if(!c){c=":wdc:"+b.g++;b[c]=a}return c}
+function ya(a,b){a=decodeURIComponent(a);var c=b||document,d=za(c);if(!(a in d))throw new n(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new n(10,"Element is no longer attached to the DOM");};function Aa(a){var b=ra;a=[a];var c;try{if(j(b))b=new Function(b);var d=W(a),e=b.apply(null,d);c={status:0,value:V(e)}}catch(f){c={status:"code"in f?f.code:13,value:{message:f.message}}}b=[];T(new ua,c,b);return b.join("")}var Y="_".split("."),Z=this;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&Aa!==undefined)Z[$]=Aa;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/get_top_left_coordinates_android.js b/core/res/res/raw/get_top_left_coordinates_android.js
new file mode 100644
index 0000000..23f96afe
--- /dev/null
+++ b/core/res/res/raw/get_top_left_coordinates_android.js
@@ -0,0 +1,18 @@
+function(){return function(){var h=this;
+function j(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if(b==
+"function"&&typeof a.call=="undefined")return"object";return b}function l(a){var b=j(a);return b=="array"||b=="object"&&typeof a.length=="number"}function aa(a){a=j(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var ba=Date.now||function(){return+new Date};function m(a,b){function c(){}c.prototype=b.prototype;a.j=b.prototype;a.prototype=new c};function n(a){this.stack=Error().stack||"";if(a)this.message=String(a)}m(n,Error);n.prototype.name="CustomError";function ca(a,b,c){var d={};for(var f in a)if(b.call(c,a[f],f,a))d[f]=a[f];return d}function o(a,b,c){var d={};for(var f in a)d[f]=b.call(c,a[f],f,a);return d}function da(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function p(a,b){n.call(this,b);this.code=a;this.name=q[a]||q[13]}m(p,n);var q,r={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},s={};for(var t in r)s[r[t]]=t;q=s;
+p.prototype.toString=function(){return"["+this.name+"] "+this.message};function ea(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a}function y(a,b){if(a<b)return-1;else if(a>b)return 1;return 0};function z(a,b){b.unshift(a);n.call(this,ea.apply(null,b));b.shift();this.k=a}m(z,n);z.prototype.name="AssertionError";function fa(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var f=c}throw new z(""+d,f||[]);}return a};var A=Array.prototype,B=A.map?function(a,b,c){fa(a.length!=null);return A.map.call(a,b,c)}:function(a,b,c){var d=a.length,f=Array(d),e=typeof a=="string"?a.split(""):a;for(var g=0;g<d;g++)if(g in e)f[g]=b.call(c,e[g],g,a);return f};var C,F="",G;if(G=/WebKit\/(\S+)/){var H=G.exec(h.navigator?h.navigator.userAgent:null);F=H?H[1]:""}C=F;var ga={};var ha;function I(a,b){this.x=a!==undefined?a:0;this.y=b!==undefined?b:0}I.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function J(a,b){this.width=a;this.height=b}J.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};J.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};function K(a){return a?new ia(L(a)):ha||(ha=new ia)}function L(a){return a.nodeType==9?a:a.ownerDocument||a.document}function ia(a){this.e=a||h.document||document}function ja(a){a=a.e.body;return new I(a.scrollLeft,a.scrollTop)};var M="StopIteration"in h?h.StopIteration:Error("StopIteration");function ka(){}ka.prototype.next=function(){throw M;};function N(a,b,c,d,f){this.a=!!b;a&&O(this,a,d);this.d=f!=undefined?f:this.c||0;if(this.a)this.d*=-1;this.h=!c}m(N,ka);N.prototype.b=null;N.prototype.c=0;N.prototype.g=false;function O(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+N.prototype.next=function(){var a;if(this.g){if(!this.b||this.h&&this.d==0)throw M;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?O(this,c):O(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?O(this,c):O(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.g=true;a=this.b;if(!this.b)throw M;return a};
+N.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;N.prototype.next.call(this);this.a=!this.a;b=l(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function P(a,b,c,d){N.call(this,a,b,c,null,d)}m(P,N);P.prototype.next=function(){do P.j.next.call(this);while(this.c==-1);return this.b};function la(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}la.prototype.toString=function(){return"("+this.top+"t, "+this.right+"r, "+this.bottom+"b, "+this.left+"l)"};function Q(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}Q.prototype.toString=function(){return"("+this.left+", "+this.top+" - "+this.width+"w x "+this.height+"h)"};function R(a,b){var c=L(a);if(c.defaultView&&c.defaultView.getComputedStyle)if(c=c.defaultView.getComputedStyle(a,null))return c[b]||c.getPropertyValue(b);return""}function S(a,b){return R(a,b)||(a.currentStyle?a.currentStyle[b]:null)||a.style[b]}
+function ma(a){var b=L(a),c=S(a,"position"),d=c=="fixed"||c=="absolute";for(a=a.parentNode;a&&a!=b;a=a.parentNode){c=S(a,"position");d=d&&c=="static"&&a!=b.documentElement&&a!=b.body;if(!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||c=="fixed"||c=="absolute"))return a}return null}
+function T(a){var b=L(a),c=S(a,"position"),d=new I(0,0),f=(b?b.nodeType==9?b:L(b):document).documentElement;if(a==f)return d;if(a.getBoundingClientRect){a=a.getBoundingClientRect();b=ja(K(b));d.x=a.left+b.x;d.y=a.top+b.y}else if(b.getBoxObjectFor){a=b.getBoxObjectFor(a);b=b.getBoxObjectFor(f);d.x=a.screenX-b.screenX;d.y=a.screenY-b.screenY}else{var e=a;do{d.x+=e.offsetLeft;d.y+=e.offsetTop;if(e!=a){d.x+=e.clientLeft||0;d.y+=e.clientTop||0}if(S(e,"position")=="fixed"){d.x+=b.body.scrollLeft;d.y+=b.body.scrollTop;
+break}e=e.offsetParent}while(e&&e!=a);if(c=="absolute")d.y-=b.body.offsetTop;for(e=a;(e=ma(e))&&e!=b.body&&e!=f;){d.x-=e.scrollLeft;d.y-=e.scrollTop}}return d};String.fromCharCode(160);function na(a,b){b.scrollLeft+=Math.min(a.left,Math.max(a.left-a.width,0));b.scrollTop+=Math.min(a.top,Math.max(a.top-a.height,0))}
+function oa(a,b){var c;c=b?new Q(b.left,b.top,b.width,b.height):new Q(0,0,a.offsetWidth,a.offsetHeight);var d=L(a);for(var f=a.parentNode;f&&f!=d.body&&f!=d.documentElement;){var e=c,g=f,u=T(a),v=T(g),i=void 0;i=void 0;var k=void 0,D=void 0,E=void 0;E=R(g,"borderLeftWidth");D=R(g,"borderRightWidth");k=R(g,"borderTopWidth");i=R(g,"borderBottomWidth");i=new la(parseFloat(k),parseFloat(D),parseFloat(i),parseFloat(E));na(new Q(u.x+e.left-v.x-i.left,u.y+e.top-v.y-i.top,g.clientWidth-e.width,g.clientHeight-
+e.height),g);f=f.parentNode}f=T(a);e=K(d);e=(e.e.parentWindow||e.e.defaultView||window).document;if(!ga["500"]){g=0;u=String(C).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");v=String("500").replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");i=Math.max(u.length,v.length);for(k=0;g==0&&k<i;k++){D=u[k]||"";E=v[k]||"";var sa=RegExp("(\\d*)(\\D*)","g"),ta=RegExp("(\\d*)(\\D*)","g");do{var w=sa.exec(D)||["","",""],x=ta.exec(E)||["","",""];if(w[0].length==0&&x[0].length==0)break;g=y(w[1].length==0?0:parseInt(w[1],
+10),x[1].length==0?0:parseInt(x[1],10))||y(w[2].length==0,x[2].length==0)||y(w[2],x[2])}while(g==0)}ga["500"]=g>=0}e=e.compatMode=="CSS1Compat"?e.documentElement:e.body;e=new J(e.clientWidth,e.clientHeight);na(new Q(f.x+c.left-d.body.scrollLeft,f.y+c.top-d.body.scrollTop,e.width-c.width,e.height-c.height),d.body);d=new I;if(a.nodeType==1)if(a.getBoundingClientRect){f=a.getBoundingClientRect();d.x=f.left;d.y=f.top}else{f=ja(K(a));e=T(a);d.x=e.x-f.x;d.y=e.y-f.y}else{f=j(a.f)=="function";e=a;if(a.targetTouches)e=
+a.targetTouches[0];else if(f&&a.f().targetTouches)e=a.f().targetTouches[0];d.x=e.clientX;d.y=e.clientY}return new I(d.x+c.left,d.y+c.top)};function pa(){}
+function U(a,b,c){switch(typeof b){case "string":qa(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(j(b)=="array"){var d=b.length;c.push("[");var f="";for(var e=0;e<d;e++){c.push(f);U(a,b[e],c);f=","}c.push("]");break}c.push("{");d="";for(f in b)if(Object.prototype.hasOwnProperty.call(b,f)){e=b[f];if(typeof e!="function"){c.push(d);qa(a,f,c);c.push(":");U(a,
+e,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var V={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},ra=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function qa(a,b,c){c.push('"',b.replace(ra,function(d){if(d in V)return V[d];var f=d.charCodeAt(0),e="\\u";if(f<16)e+="000";else if(f<256)e+="00";else if(f<4096)e+="0";return V[d]=e+f.toString(16)}),'"')};function W(a){switch(j(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return B(a,W);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=ua(a);return b}if(l(a))return B(a,W);a=ca(a,function(c,d){return typeof d=="number"||typeof d=="string"});return o(a,W);default:return null}}
+function X(a,b){if(j(a)=="array")return B(a,function(c){return X(c,b)});else if(aa(a))return"ELEMENT"in a?va(a.ELEMENT,b):o(a,function(c){return X(c,b)});return a}function wa(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.i=ba()}return b}function ua(a){var b=wa(a.ownerDocument),c=da(b,function(d){return d==a});if(!c){c=":wdc:"+b.i++;b[c]=a}return c}
+function va(a,b){a=decodeURIComponent(a);var c=b||document,d=wa(c);if(!(a in d))throw new p(10,"Element does not exist in cache");var f=d[a];for(var e=f;e;){if(e==c.documentElement)return f;e=e.parentNode}delete d[a];throw new p(10,"Element is no longer attached to the DOM");};function xa(a){var b=oa;a=[a];var c;try{if(typeof b=="string")b=new Function(b);var d=X(a),f=b.apply(null,d);c={status:0,value:W(f)}}catch(e){c={status:"code"in e?e.code:13,value:{message:e.message}}}b=[];U(new pa,c,b);return b.join("")}var Y="_".split("."),Z=h;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&xa!==undefined)Z[$]=xa;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/get_value_of_css_property_android.js b/core/res/res/raw/get_value_of_css_property_android.js
new file mode 100644
index 0000000..c156dec
--- /dev/null
+++ b/core/res/res/raw/get_value_of_css_property_android.js
@@ -0,0 +1,10 @@
+function(){return function(){function g(a){var c=typeof a;if(c=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return c;var b=Object.prototype.toString.call(a);if(b=="[object Window]")return"object";if(b=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(b=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(c=="function"&&typeof a.call=="undefined")return"object";return c}function i(a){var c=g(a);return c=="array"||c=="object"&&typeof a.length=="number"}function j(a){a=g(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var k=Date.now||function(){return+new Date};function l(a,c){function b(){}b.prototype=c.prototype;a.h=c.prototype;a.prototype=new b};function m(a){this.stack=Error().stack||"";if(a)this.message=String(a)}l(m,Error);m.prototype.name="CustomError";function n(a,c,b){var d={};for(var e in a)if(c.call(b,a[e],e,a))d[e]=a[e];return d}function o(a,c,b){var d={};for(var e in a)d[e]=c.call(b,a[e],e,a);return d}function p(a,c,b){for(var d in a)if(c.call(b,a[d],d,a))return d};function q(a,c){m.call(this,c);this.code=a;this.name=r[a]||r[13]}l(q,m);var r,s={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},t={};for(var u in s)t[s[u]]=u;r=t;
+q.prototype.toString=function(){return"["+this.name+"] "+this.message};function v(a){for(var c=1;c<arguments.length;c++){var b=String(arguments[c]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,b)}return a};function w(a,c){c.unshift(a);m.call(this,v.apply(null,c));c.shift();this.i=a}l(w,m);w.prototype.name="AssertionError";function x(a,c){if(!a){var b=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(c){d+=": "+c;var e=b}throw new w(""+d,e||[]);}return a};var y=Array.prototype,A=y.map?function(a,c,b){x(a.length!=null);return y.map.call(a,c,b)}:function(a,c,b){var d=a.length,e=Array(d),f=typeof a=="string"?a.split(""):a;for(var h=0;h<d;h++)if(h in f)e[h]=c.call(b,f[h],h,a);return e};var B="",C;if(C=/WebKit\/(\S+)/){var D=C.exec(this.navigator?this.navigator.userAgent:null);B=D?D[1]:""};var E="StopIteration"in this?this.StopIteration:Error("StopIteration");function F(){}F.prototype.next=function(){throw E;};function G(a,c,b,d,e){this.a=!!c;a&&H(this,a,d);this.d=e!=undefined?e:this.c||0;if(this.a)this.d*=-1;this.f=!b}l(G,F);G.prototype.b=null;G.prototype.c=0;G.prototype.e=false;function H(a,c,b,d){if(a.b=c)a.c=typeof b=="number"?b:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+G.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&this.d==0)throw E;a=this.b;var c=this.a?-1:1;if(this.c==c){var b=this.a?a.lastChild:a.firstChild;b?H(this,b):H(this,a,c*-1)}else(b=this.a?a.previousSibling:a.nextSibling)?H(this,b):H(this,a.parentNode,c*-1);this.d+=this.c*(this.a?-1:1)}else this.e=true;a=this.b;if(!this.b)throw E;return a};
+G.prototype.splice=function(){var a=this.b,c=this.a?1:-1;if(this.c==c){this.c=c*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;G.prototype.next.call(this);this.a=!this.a;c=i(arguments[0])?arguments[0]:arguments;for(var b=c.length-1;b>=0;b--)a.parentNode&&a.parentNode.insertBefore(c[b],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function I(a,c,b,d){G.call(this,a,c,b,null,d)}l(I,G);I.prototype.next=function(){do I.h.next.call(this);while(this.c==-1);return this.b};function J(a,c){var b=(a.currentStyle||a.style)[c];if(b!="inherit")return b!==undefined?b:null;for(b=a.parentNode;b&&b.nodeType!=1&&b.nodeType!=9&&b.nodeType!=11;)b=b.parentNode;return(b=b&&b.nodeType==1&&1?b:null)?J(b,c):null}String.fromCharCode(160);function K(){}
+function L(a,c,b){switch(typeof c){case "string":M(a,c,b);break;case "number":b.push(isFinite(c)&&!isNaN(c)?c:"null");break;case "boolean":b.push(c);break;case "undefined":b.push("null");break;case "object":if(c==null){b.push("null");break}if(g(c)=="array"){var d=c.length;b.push("[");var e="";for(var f=0;f<d;f++){b.push(e);L(a,c[f],b);e=","}b.push("]");break}b.push("{");d="";for(e in c)if(Object.prototype.hasOwnProperty.call(c,e)){f=c[e];if(typeof f!="function"){b.push(d);M(a,e,b);b.push(":");L(a,
+f,b);d=","}}b.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof c);}}var N={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},O=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function M(a,c,b){b.push('"',c.replace(O,function(d){if(d in N)return N[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return N[d]=f+e.toString(16)}),'"')};function P(a){switch(g(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return A(a,P);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var c={};c.ELEMENT=Q(a);return c}if(i(a))return A(a,P);a=n(a,function(b,d){return typeof d=="number"||typeof d=="string"});return o(a,P);default:return null}}
+function R(a,c){if(g(a)=="array")return A(a,function(b){return R(b,c)});else if(j(a))return"ELEMENT"in a?S(a.ELEMENT,c):o(a,function(b){return R(b,c)});return a}function T(a){a=a||document;var c=a.$wdc_;if(!c){c=a.$wdc_={};c.g=k()}return c}function Q(a){var c=T(a.ownerDocument),b=p(c,function(d){return d==a});if(!b){b=":wdc:"+c.g++;c[b]=a}return b}
+function S(a,c){a=decodeURIComponent(a);var b=c||document,d=T(b);if(!(a in d))throw new q(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==b.documentElement)return e;f=f.parentNode}delete d[a];throw new q(10,"Element is no longer attached to the DOM");};function U(a,c){var b=J,d=[a,c],e;try{if(typeof b=="string")b=new Function(b);var f=R(d),h=b.apply(null,f);e={status:0,value:P(h)}}catch(z){e={status:"code"in z?z.code:13,value:{message:z.message}}}b=[];L(new K,e,b);return b.join("")}var V="_".split("."),W=this;!(V[0]in W)&&W.execScript&&W.execScript("var "+V[0]);for(var X;V.length&&(X=V.shift());)if(!V.length&&U!==undefined)W[X]=U;else W=W[X]?W[X]:W[X]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/is_enabled_android.js b/core/res/res/raw/is_enabled_android.js
new file mode 100644
index 0000000..3f799f3
--- /dev/null
+++ b/core/res/res/raw/is_enabled_android.js
@@ -0,0 +1,12 @@
+function(){return function(){function g(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(b=="function"&&typeof a.call=="undefined")return"object";return b}function h(a){var b=g(a);return b=="array"||b=="object"&&typeof a.length=="number"}function i(a){return typeof a=="string"}function k(a){a=g(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var l=Date.now||function(){return+new Date};function m(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function n(a){this.stack=Error().stack||"";if(a)this.message=String(a)}m(n,Error);n.prototype.name="CustomError";function o(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function p(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function q(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function r(a,b){n.call(this,b);this.code=a;this.name=s[a]||s[13]}m(r,n);var s,t={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},u={};for(var v in t)u[t[v]]=v;s=u;
+r.prototype.toString=function(){return"["+this.name+"] "+this.message};function w(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a};function x(a,b){b.unshift(a);n.call(this,w.apply(null,b));b.shift();this.i=a}m(x,n);x.prototype.name="AssertionError";function y(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new x(""+d,e||[]);}return a};var z=Array.prototype,A=z.indexOf?function(a,b,c){y(a.length!=null);return z.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(i(a)){if(!i(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},B=z.map?function(a,b,c){y(a.length!=null);return z.map.call(a,b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=i(a)?a.split(""):a;for(var j=0;j<d;j++)if(j in f)e[j]=b.call(c,f[j],j,a);return e};var C="",D;if(D=/WebKit\/(\S+)/){var E=D.exec(this.navigator?this.navigator.userAgent:null);C=E?E[1]:""};var F="StopIteration"in this?this.StopIteration:Error("StopIteration");function G(){}G.prototype.next=function(){throw F;};function H(a,b,c,d,e){this.a=!!b;a&&I(this,a,d);this.d=e!=undefined?e:this.c||0;if(this.a)this.d*=-1;this.f=!c}m(H,G);H.prototype.b=null;H.prototype.c=0;H.prototype.e=false;function I(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+H.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&this.d==0)throw F;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?I(this,c):I(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?I(this,c):I(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.e=true;a=this.b;if(!this.b)throw F;return a};
+H.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;H.prototype.next.call(this);this.a=!this.a;b=h(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function J(a,b,c,d){H.call(this,a,b,c,null,d)}m(J,H);J.prototype.next=function(){do J.h.next.call(this);while(this.c==-1);return this.b};var K=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking","selected","spellcheck","truespeed","willvalidate"];
+function L(a,b){if(8==a.nodeType)return null;b=b.toLowerCase();if(b=="style"){var c=a.style.cssText.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").toLowerCase();return c.charAt(c.length-1)==";"?c:c+";"}c=a.getAttributeNode(b);if(!c)return null;if(A(K,b)>=0)return"true";return c.specified?c.value:null}var M=["BUTTON","INPUT","OPTGROUP","OPTION","SELECT","TEXTAREA"];
+function N(a){var b=a.tagName.toUpperCase();if(!(A(M,b)>=0))return true;if(L(a,"disabled"))return false;if(a.parentNode&&a.parentNode.nodeType==1&&"OPTGROUP"==b||"OPTION"==b)return N(a.parentNode);return true}String.fromCharCode(160);function O(){}
+function P(a,b,c){switch(typeof b){case "string":Q(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(g(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);P(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);Q(a,e,c);c.push(":");P(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var R={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},S=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function Q(a,b,c){c.push('"',b.replace(S,function(d){if(d in R)return R[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return R[d]=f+e.toString(16)}),'"')};function T(a){switch(g(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return B(a,T);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=U(a);return b}if(h(a))return B(a,T);a=o(a,function(c,d){return typeof d=="number"||i(d)});return p(a,T);default:return null}}
+function V(a,b){if(g(a)=="array")return B(a,function(c){return V(c,b)});else if(k(a))return"ELEMENT"in a?aa(a.ELEMENT,b):p(a,function(c){return V(c,b)});return a}function W(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.g=l()}return b}function U(a){var b=W(a.ownerDocument),c=q(b,function(d){return d==a});if(!c){c=":wdc:"+b.g++;b[c]=a}return c}
+function aa(a,b){a=decodeURIComponent(a);var c=b||document,d=W(c);if(!(a in d))throw new r(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new r(10,"Element is no longer attached to the DOM");};function X(a){var b=N;a=[a];var c;try{if(i(b))b=new Function(b);var d=V(a),e=b.apply(null,d);c={status:0,value:T(e)}}catch(f){c={status:"code"in f?f.code:13,value:{message:f.message}}}b=[];P(new O,c,b);return b.join("")}var Y="_".split("."),Z=this;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&X!==undefined)Z[$]=X;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/is_selected_android.js b/core/res/res/raw/is_selected_android.js
new file mode 100644
index 0000000..0cc53b2
--- /dev/null
+++ b/core/res/res/raw/is_selected_android.js
@@ -0,0 +1,10 @@
+function(){return function(){function g(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if(b=="function"&&typeof a.call=="undefined")return"object";return b}function h(a){var b=g(a);return b=="array"||b=="object"&&typeof a.length=="number"}function i(a){return typeof a=="string"}function k(a){a=g(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var l=Date.now||function(){return+new Date};function m(a,b){function c(){}c.prototype=b.prototype;a.h=b.prototype;a.prototype=new c};function n(a){this.stack=Error().stack||"";if(a)this.message=String(a)}m(n,Error);n.prototype.name="CustomError";function o(a,b,c){var d={};for(var e in a)if(b.call(c,a[e],e,a))d[e]=a[e];return d}function p(a,b,c){var d={};for(var e in a)d[e]=b.call(c,a[e],e,a);return d}function q(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function r(a,b){n.call(this,b);this.code=a;this.name=s[a]||s[13]}m(r,n);var s,t={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},u={};for(var v in t)u[t[v]]=v;s=u;
+r.prototype.toString=function(){return"["+this.name+"] "+this.message};function w(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a};function x(a,b){b.unshift(a);n.call(this,w.apply(null,b));b.shift();this.i=a}m(x,n);x.prototype.name="AssertionError";function y(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var e=c}throw new x(""+d,e||[]);}return a};var z=Array.prototype,A=z.indexOf?function(a,b,c){y(a.length!=null);return z.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(i(a)){if(!i(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},B=z.map?function(a,b,c){y(a.length!=null);return z.map.call(a,b,c)}:function(a,b,c){var d=a.length,e=Array(d),f=i(a)?a.split(""):a;for(var j=0;j<d;j++)if(j in f)e[j]=b.call(c,f[j],j,a);return e};var C="",D;if(D=/WebKit\/(\S+)/){var E=D.exec(this.navigator?this.navigator.userAgent:null);C=E?E[1]:""};var F="StopIteration"in this?this.StopIteration:Error("StopIteration");function G(){}G.prototype.next=function(){throw F;};function H(a,b,c,d,e){this.a=!!b;a&&I(this,a,d);this.d=e!=undefined?e:this.c||0;if(this.a)this.d*=-1;this.f=!c}m(H,G);H.prototype.b=null;H.prototype.c=0;H.prototype.e=false;function I(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+H.prototype.next=function(){var a;if(this.e){if(!this.b||this.f&&this.d==0)throw F;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?I(this,c):I(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?I(this,c):I(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.e=true;a=this.b;if(!this.b)throw F;return a};
+H.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;H.prototype.next.call(this);this.a=!this.a;b=h(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function J(a,b,c,d){H.call(this,a,b,c,null,d)}m(J,H);J.prototype.next=function(){do J.h.next.call(this);while(this.c==-1);return this.b};var K={"class":"className",readonly:"readOnly"},L=["checked","disabled","draggable","hidden"];String.fromCharCode(160);function M(a){var b;if(a&&a.nodeType==1&&a.tagName.toUpperCase()=="OPTION")b=true;else if(a&&a.nodeType==1&&a.tagName.toUpperCase()=="INPUT"){b=a.type.toLowerCase();b=b=="checkbox"||b=="radio"}else b=false;if(!b)throw new r(15,"Element is not selectable");b="selected";var c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";b=K[b]||b;a=a[b];a=a===undefined&&A(L,b)>=0?false:a;return!!a};function N(){}
+function O(a,b,c){switch(typeof b){case "string":P(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(g(b)=="array"){var d=b.length;c.push("[");var e="";for(var f=0;f<d;f++){c.push(e);O(a,b[f],c);e=","}c.push("]");break}c.push("{");d="";for(e in b)if(Object.prototype.hasOwnProperty.call(b,e)){f=b[e];if(typeof f!="function"){c.push(d);P(a,e,c);c.push(":");O(a,
+f,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var Q={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},R=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function P(a,b,c){c.push('"',b.replace(R,function(d){if(d in Q)return Q[d];var e=d.charCodeAt(0),f="\\u";if(e<16)f+="000";else if(e<256)f+="00";else if(e<4096)f+="0";return Q[d]=f+e.toString(16)}),'"')};function S(a){switch(g(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return B(a,S);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=T(a);return b}if(h(a))return B(a,S);a=o(a,function(c,d){return typeof d=="number"||i(d)});return p(a,S);default:return null}}
+function U(a,b){if(g(a)=="array")return B(a,function(c){return U(c,b)});else if(k(a))return"ELEMENT"in a?V(a.ELEMENT,b):p(a,function(c){return U(c,b)});return a}function W(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.g=l()}return b}function T(a){var b=W(a.ownerDocument),c=q(b,function(d){return d==a});if(!c){c=":wdc:"+b.g++;b[c]=a}return c}
+function V(a,b){a=decodeURIComponent(a);var c=b||document,d=W(c);if(!(a in d))throw new r(10,"Element does not exist in cache");var e=d[a];for(var f=e;f;){if(f==c.documentElement)return e;f=f.parentNode}delete d[a];throw new r(10,"Element is no longer attached to the DOM");};function X(a){var b=M;a=[a];var c;try{if(i(b))b=new Function(b);var d=U(a),e=b.apply(null,d);c={status:0,value:S(e)}}catch(f){c={status:"code"in f?f.code:13,value:{message:f.message}}}b=[];O(new N,c,b);return b.join("")}var Y="_".split("."),Z=this;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&X!==undefined)Z[$]=X;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/set_selected_android.js b/core/res/res/raw/set_selected_android.js
new file mode 100644
index 0000000..51774e0
--- /dev/null
+++ b/core/res/res/raw/set_selected_android.js
@@ -0,0 +1,26 @@
+function(){return function(){var l=this;
+function m(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if(b==
+"function"&&typeof a.call=="undefined")return"object";return b}function o(a){var b=m(a);return b=="array"||b=="object"&&typeof a.length=="number"}function p(a){return typeof a=="string"}function q(a){a=m(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var aa=Date.now||function(){return+new Date};function r(a,b){function c(){}c.prototype=b.prototype;a.j=b.prototype;a.prototype=new c};function s(a){this.stack=Error().stack||"";if(a)this.message=String(a)}r(s,Error);s.prototype.name="CustomError";function ba(a,b,c){var d={};for(var f in a)if(b.call(c,a[f],f,a))d[f]=a[f];return d}function u(a,b,c){var d={};for(var f in a)d[f]=b.call(c,a[f],f,a);return d}function ca(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function v(a,b){s.call(this,b);this.code=a;this.name=w[a]||w[13]}r(v,s);var w,da={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},ea={};for(var fa in da)ea[da[fa]]=fa;w=ea;
+v.prototype.toString=function(){return"["+this.name+"] "+this.message};var ga=window;function ha(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a}var ia={};function ja(a){return ia[a]||(ia[a]=String(a).replace(/\-([a-z])/g,function(b,c){return c.toUpperCase()}))};function x(a,b){b.unshift(a);s.call(this,ha.apply(null,b));b.shift();this.m=a}r(x,s);x.prototype.name="AssertionError";function y(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var f=c}throw new x(""+d,f||[]);}return a};var z=Array.prototype,A=z.indexOf?function(a,b,c){y(a.length!=null);return z.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(p(a)){if(!p(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},B=z.map?function(a,b,c){y(a.length!=null);return z.map.call(a,b,c)}:function(a,b,c){var d=a.length,f=Array(d),e=p(a)?a.split(""):a;for(var g=0;g<d;g++)if(g in e)f[g]=b.call(c,e[g],g,a);return f},ka=z.some?function(a,b,c){y(a.length!=
+null);return z.some.call(a,b,c)}:function(a,b,c){var d=a.length,f=p(a)?a.split(""):a;for(var e=0;e<d;e++)if(e in f&&b.call(c,f[e],e,a))return true;return false};var C=true,la="",D;if(C)D=/WebKit\/(\S+)/;if(D){var ma=D.exec(l.navigator?l.navigator.userAgent:null);la=ma?ma[1]:""};var E;function F(a,b){this.x=a!==undefined?a:0;this.y=b!==undefined?b:0}F.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function G(a,b){this.width=a;this.height=b}G.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};G.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};function H(a){return a.nodeType==9?a:a.ownerDocument||a.document}function na(a,b){var c=[];return oa(a,b,c,true)?c[0]:undefined}function oa(a,b,c,d){if(a!=null){var f=0;for(var e;e=a.childNodes[f];f++){if(b(e)){c.push(e);if(d)return true}if(oa(e,b,c,d))return true}}return false}function I(a,b,c,d){if(!c)a=a.parentNode;c=d==null;for(var f=0;a&&(c||f<=d);){if(b(a))return a;a=a.parentNode;f++}return null}function J(a){this.e=a||l.document||document}
+function pa(a){a=!C&&a.e.compatMode=="CSS1Compat"?a.e.documentElement:a.e.body;return new F(a.scrollLeft,a.scrollTop)};function qa(a,b){try{var c;if(typeof b.selectSingleNode!="undefined"){var d=H(b);typeof d.setProperty!="undefined"&&d.setProperty("SelectionLanguage","XPath");c=b.selectSingleNode(a)}else if(document.implementation.hasFeature("XPath","3.0")){d=H(b);var f=d.createNSResolver(d.documentElement);c=d.evaluate(a,b,f,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}else c=null}catch(e){return null}if(!c)return null;if(c.nodeType!=1)throw Error("Returned node is not an element: "+a);return c};var K="StopIteration"in l?l.StopIteration:Error("StopIteration");function ra(){}ra.prototype.next=function(){throw K;};function L(a,b,c,d,f){this.a=!!b;a&&M(this,a,d);this.d=f!=undefined?f:this.c||0;if(this.a)this.d*=-1;this.h=!c}r(L,ra);L.prototype.b=null;L.prototype.c=0;L.prototype.g=false;function M(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+L.prototype.next=function(){var a;if(this.g){if(!this.b||this.h&&this.d==0)throw K;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?M(this,c):M(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?M(this,c):M(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.g=true;a=this.b;if(!this.b)throw K;return a};
+L.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;L.prototype.next.call(this);this.a=!this.a;b=o(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function N(a,b,c,d){L.call(this,a,b,c,null,d)}r(N,L);N.prototype.next=function(){do N.j.next.call(this);while(this.c==-1);return this.b};function sa(a,b){var c=H(a);if(c.defaultView&&c.defaultView.getComputedStyle)if(c=c.defaultView.getComputedStyle(a,null))return c[b]||c.getPropertyValue(b);return""}function O(a,b){return sa(a,b)||(a.currentStyle?a.currentStyle[b]:null)||a.style[b]}
+function ta(a){var b=H(a),c=O(a,"position"),d=c=="fixed"||c=="absolute";for(a=a.parentNode;a&&a!=b;a=a.parentNode){c=O(a,"position");d=d&&c=="static"&&a!=b.documentElement&&a!=b.body;if(!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||c=="fixed"||c=="absolute"))return a}return null};function P(a,b){return!!a&&a.nodeType==1&&(!b||a.tagName.toUpperCase()==b)}
+var ua={"class":"className",readonly:"readOnly"},va=["checked","disabled","draggable","hidden"],wa=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking",
+"selected","spellcheck","truespeed","willvalidate"];function xa(a,b){if(8==a.nodeType)return null;b=b.toLowerCase();if(b=="style"){var c=a.style.cssText.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").toLowerCase();return c.charAt(c.length-1)==";"?c:c+";"}c=a.getAttributeNode(b);if(!c)return null;if(A(wa,b)>=0)return"true";return c.specified?c.value:null}var ya=["BUTTON","INPUT","OPTGROUP","OPTION","SELECT","TEXTAREA"];
+function za(a){var b=a.tagName.toUpperCase();if(!(A(ya,b)>=0))return true;if(xa(a,"disabled"))return false;if(a.parentNode&&a.parentNode.nodeType==1&&"OPTGROUP"==b||"OPTION"==b)return za(a.parentNode);return true}function Q(a){for(a=a.parentNode;a&&a.nodeType!=1&&a.nodeType!=9&&a.nodeType!=11;)a=a.parentNode;return P(a)?a:null}function R(a,b){b=ja(String(b));return sa(a,b)||Aa(a,b)}
+function Aa(a,b){var c=(a.currentStyle||a.style)[b];if(c!="inherit")return c!==undefined?c:null;return(c=Q(a))?Aa(c,b):null}function Ba(a){if(m(a.getBBox)=="function")return a.getBBox();var b;if(O(a,"display")!="none")b=new G(a.offsetWidth,a.offsetHeight);else{b=a.style;var c=b.display,d=b.visibility,f=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";var e;e=a.offsetWidth;a=a.offsetHeight;b.display=c;b.position=f;b.visibility=d;b=new G(e,a)}return b}
+function S(a,b){function c(e){if(R(e,"display")=="none")return false;e=Q(e);return!e||c(e)}function d(e){var g=Ba(e);if(g.height>0&&g.width>0)return true;if(e.innerText||e.textContent)if(Ca.test(e.innerText||e.textContent))return true;return C&&ka(e.childNodes,function(k){return P(k)&&d(k)})}if(!P(a))throw Error("Argument to isShown must be of type Element");if(P(a,"TITLE"))return(H(a)?H(a).parentWindow||H(a).defaultView:window)==ga;if(P(a,"OPTION")||P(a,"OPTGROUP")){var f=I(a,function(e){return P(e,
+"SELECT")});return!!f&&S(f)}if(P(a,"MAP")){if(!a.name)return false;f=H(a);f=f.evaluate?qa('/descendant::*[@usemap = "#'+a.name+'"]',f):na(f,function(e){return P(e)&&xa(e,"usemap")=="#"+a.name});return!!f&&S(f)}if(P(a,"AREA")){f=I(a,function(e){return P(e,"MAP")});return!!f&&S(f)}if(P(a,"INPUT")&&a.type.toLowerCase()=="hidden")return false;if(R(a,"visibility")=="hidden")return false;if(!c(a))return false;if(!b&&Da(a)==0)return false;if(!d(a))return false;return true}
+var Ea="[\\s\\xa0"+String.fromCharCode(160)+"]+",Ca=RegExp("^"+Ea+"$");function Da(a){var b=1,c=R(a,"opacity");if(c)b=Number(c);if(a=Q(a))b*=Da(a);return b};var Fa=["dragstart","dragexit","mouseover","mouseout"];
+function T(a,b,c){var d=H(a),f=d?d.parentWindow||d.defaultView:window,e=new F;if(a.nodeType==1)if(a.getBoundingClientRect){var g=a.getBoundingClientRect();e.x=g.left;e.y=g.top}else{g=pa(a?new J(H(a)):E||(E=new J));var k,h=H(a);k=O(a,"position");var i=new F(0,0),t=(h?h.nodeType==9?h:H(h):document).documentElement;if(a!=t)if(a.getBoundingClientRect){k=a.getBoundingClientRect();h=pa(h?new J(H(h)):E||(E=new J));i.x=k.left+h.x;i.y=k.top+h.y}else if(h.getBoxObjectFor){k=h.getBoxObjectFor(a);h=h.getBoxObjectFor(t);
+i.x=k.screenX-h.screenX;i.y=k.screenY-h.screenY}else{var j=a;do{i.x+=j.offsetLeft;i.y+=j.offsetTop;if(j!=a){i.x+=j.clientLeft||0;i.y+=j.clientTop||0}if(C&&O(j,"position")=="fixed"){i.x+=h.body.scrollLeft;i.y+=h.body.scrollTop;break}j=j.offsetParent}while(j&&j!=a);if(C&&k=="absolute")i.y-=h.body.offsetTop;for(j=a;(j=ta(j))&&j!=h.body&&j!=t;){i.x-=j.scrollLeft;i.y-=j.scrollTop}}e.x=i.x-g.x;e.y=i.y-g.y}else{g=m(a.f)=="function";i=a;if(a.targetTouches)i=a.targetTouches[0];else if(g&&a.f().targetTouches)i=
+a.f().targetTouches[0];e.x=i.clientX;e.y=i.clientY}var n=c||{};c=(n.x||0)+e.x;e=(n.y||0)+e.y;g=n.button||0;i=n.bubble||true;k=null;if(A(Fa,b)>=0)k=n.related||null;h=!!n.alt;t=!!n.control;j=!!n.shift;n=!!n.meta;if(a.fireEvent&&d&&d.createEventObject){a=d.createEventObject();a.altKey=h;a.k=t;a.metaKey=n;a.shiftKey=j;a.clientX=c;a.clientY=e;a.button=g;a.relatedTarget=k}else{a=d.createEvent("MouseEvents");if(a.initMouseEvent)a.initMouseEvent(b,i,true,f,1,0,0,c,e,t,h,j,n,g,k);else{a.initEvent(b,i,true);
+a.shiftKey=j;a.metaKey=n;a.altKey=h;a.ctrlKey=t;a.button=g}}return a}function U(a,b,c){var d=c||{};c=d.keyCode||0;var f=d.charCode||0,e=!!d.alt,g=!!d.ctrl,k=!!d.shift;d=!!d.meta;a=H(a).createEvent("Events");a.initEvent(b,true,true);a.charCode=f;a.keyCode=c;a.altKey=e;a.ctrlKey=g;a.metaKey=d;a.shiftKey=k;return a}
+function Ga(a,b,c){var d=H(a),f=c||{};c=f.bubble!==false;var e=!!f.alt,g=!!f.control,k=!!f.shift;f=!!f.meta;if(a.fireEvent&&d&&d.createEventObject){a=d.createEventObject();a.altKey=e;a.l=g;a.metaKey=f;a.shiftKey=k}else{a=d.createEvent("HTMLEvents");a.initEvent(b,c,true);a.shiftKey=k;a.metaKey=f;a.altKey=e;a.ctrlKey=g}return a}var V={};V.click=T;V.keydown=U;V.keypress=U;V.keyup=U;V.mousedown=T;V.mousemove=T;V.mouseout=T;V.mouseover=T;V.mouseup=T;
+function Ha(a,b,c){c=(V[b]||Ga)(a,b,c);if(m(a.fireEvent)=="function"||q(a.fireEvent)){try{(H(a)?H(a).parentWindow||H(a).defaultView:window).event=c}catch(d){}a=a.fireEvent("on"+b,c)}else a=a.dispatchEvent(c);return a};function Ia(a){var b;if(P(a,"OPTION"))b=true;else if(P(a,"INPUT")){b=a.type.toLowerCase();b=b=="checkbox"||b=="radio"}else b=false;if(!b)throw new v(15,"Element is not selectable");b="selected";var c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";b=ua[b]||b;a=a[b];a=a===undefined&&A(va,b)>=0?false:a;return!!a}function Ja(a){return P(a,"SELECT")}
+function Ka(a,b){if(!za(a))throw new v(12,"Element is not currently enabled and may not be manipulated");if(!S(a,true))throw new v(11,"Element is not currently visible and may not be manipulated");if(P(a,"INPUT")){var c=a.type.toLowerCase();if(c=="checkbox"||c=="radio"){if(a.checked!=b){if(a.type=="radio"&&!b)throw new v(12,"You may not deselect a radio button");if(b!=Ia(a)){a.checked=b;Ha(a,"change")}}}else throw new v(15,"You may not select an unselectable input element: "+a.type);}else if(P(a,
+"OPTION")){c=I(a,Ja);if(!c.multiple&&!b)throw new v(15,"You may not deselect an option within a select that does not support multiple selections.");if(b!=Ia(a)){a.selected=b;Ha(c,"change")}}else throw new v(15,"You may not select an unselectable element: "+a.tagName);};function W(a){switch(m(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return B(a,W);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=La(a);return b}if(o(a))return B(a,W);a=ba(a,function(c,d){return typeof d=="number"||p(d)});return u(a,W);default:return null}}
+function X(a,b){if(m(a)=="array")return B(a,function(c){return X(c,b)});else if(q(a))return"ELEMENT"in a?Ma(a.ELEMENT,b):u(a,function(c){return X(c,b)});return a}function Na(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.i=aa()}return b}function La(a){var b=Na(a.ownerDocument),c=ca(b,function(d){return d==a});if(!c){c=":wdc:"+b.i++;b[c]=a}return c}
+function Ma(a,b){a=decodeURIComponent(a);var c=b||document,d=Na(c);if(!(a in d))throw new v(10,"Element does not exist in cache");var f=d[a];for(var e=f;e;){if(e==c.documentElement)return f;e=e.parentNode}delete d[a];throw new v(10,"Element is no longer attached to the DOM");};function Oa(a,b){var c=Ka,d=[a,b];try{if(p(c))c=new Function(c);var f=X(d),e=c.apply(null,f);W(e)}catch(g){}}var Y="_".split("."),Z=l;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&Oa!==undefined)Z[$]=Oa;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/toggle_android.js b/core/res/res/raw/toggle_android.js
new file mode 100644
index 0000000..d4f4934
--- /dev/null
+++ b/core/res/res/raw/toggle_android.js
@@ -0,0 +1,29 @@
+function(){return function(){var l=this;
+function m(a){var b=typeof a;if(b=="object")if(a){if(a instanceof Array)return"array";else if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(c=="[object Window]")return"object";if(c=="[object Array]"||typeof a.length=="number"&&typeof a.splice!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("splice"))return"array";if(c=="[object Function]"||typeof a.call!="undefined"&&typeof a.propertyIsEnumerable!="undefined"&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if(b==
+"function"&&typeof a.call=="undefined")return"object";return b}function aa(a){var b=m(a);return b=="array"||b=="object"&&typeof a.length=="number"}function o(a){return typeof a=="string"}function ba(a){a=m(a);return a=="object"||a=="array"||a=="function"}Math.floor(Math.random()*2147483648).toString(36);var ca=Date.now||function(){return+new Date};function p(a,b){function c(){}c.prototype=b.prototype;a.j=b.prototype;a.prototype=new c};function q(a){this.stack=Error().stack||"";if(a)this.message=String(a)}p(q,Error);q.prototype.name="CustomError";function da(a,b,c){var d={};for(var f in a)if(b.call(c,a[f],f,a))d[f]=a[f];return d}function ea(a,b,c){var d={};for(var f in a)d[f]=b.call(c,a[f],f,a);return d}function fa(a,b,c){for(var d in a)if(b.call(c,a[d],d,a))return d};function r(a,b){q.call(this,b);this.code=a;this.name=s[a]||s[13]}p(r,q);var s,ga={NoSuchElementError:7,NoSuchFrameError:8,UnknownCommandError:9,StaleElementReferenceError:10,ElementNotVisibleError:11,InvalidElementStateError:12,UnknownError:13,ElementNotSelectableError:15,XPathLookupError:19,NoSuchWindowError:23,InvalidCookieDomainError:24,UnableToSetCookieError:25,ModalDialogOpenedError:26,ModalDialogOpenError:27,ScriptTimeoutError:28},ha={};for(var ia in ga)ha[ga[ia]]=ia;s=ha;
+r.prototype.toString=function(){return"["+this.name+"] "+this.message};var ja=window;function ka(a){for(var b=1;b<arguments.length;b++){var c=String(arguments[b]).replace(/\$/g,"$$$$");a=a.replace(/\%s/,c)}return a}var la={};function ma(a){return la[a]||(la[a]=String(a).replace(/\-([a-z])/g,function(b,c){return c.toUpperCase()}))};function u(a,b){b.unshift(a);q.call(this,ka.apply(null,b));b.shift();this.m=a}p(u,q);u.prototype.name="AssertionError";function v(a,b){if(!a){var c=Array.prototype.slice.call(arguments,2),d="Assertion failed";if(b){d+=": "+b;var f=c}throw new u(""+d,f||[]);}return a};var w=Array.prototype,x=w.indexOf?function(a,b,c){v(a.length!=null);return w.indexOf.call(a,b,c)}:function(a,b,c){c=c==null?0:c<0?Math.max(0,a.length+c):c;if(o(a)){if(!o(b)||b.length!=1)return-1;return a.indexOf(b,c)}for(c=c;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1},y=w.map?function(a,b,c){v(a.length!=null);return w.map.call(a,b,c)}:function(a,b,c){var d=a.length,f=Array(d),e=o(a)?a.split(""):a;for(var g=0;g<d;g++)if(g in e)f[g]=b.call(c,e[g],g,a);return f},na=w.some?function(a,b,c){v(a.length!=
+null);return w.some.call(a,b,c)}:function(a,b,c){var d=a.length,f=o(a)?a.split(""):a;for(var e=0;e<d;e++)if(e in f&&b.call(c,f[e],e,a))return true;return false};var z=true,oa="",A;if(z)A=/WebKit\/(\S+)/;if(A){var pa=A.exec(l.navigator?l.navigator.userAgent:null);oa=pa?pa[1]:""};var B;function C(a,b){this.x=a!==undefined?a:0;this.y=b!==undefined?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};function E(a){return a.nodeType==9?a:a.ownerDocument||a.document}function qa(a,b){var c=[];return ra(a,b,c,true)?c[0]:undefined}function ra(a,b,c,d){if(a!=null){var f=0;for(var e;e=a.childNodes[f];f++){if(b(e)){c.push(e);if(d)return true}if(ra(e,b,c,d))return true}}return false}function F(a,b,c,d){if(!c)a=a.parentNode;c=d==null;for(var f=0;a&&(c||f<=d);){if(b(a))return a;a=a.parentNode;f++}return null}function G(a){this.e=a||l.document||document}
+function sa(a){a=!z&&a.e.compatMode=="CSS1Compat"?a.e.documentElement:a.e.body;return new C(a.scrollLeft,a.scrollTop)};function ta(a,b){try{var c;if(typeof b.selectSingleNode!="undefined"){var d=E(b);typeof d.setProperty!="undefined"&&d.setProperty("SelectionLanguage","XPath");c=b.selectSingleNode(a)}else if(document.implementation.hasFeature("XPath","3.0")){d=E(b);var f=d.createNSResolver(d.documentElement);c=d.evaluate(a,b,f,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}else c=null}catch(e){return null}if(!c)return null;if(c.nodeType!=1)throw Error("Returned node is not an element: "+a);return c};var H="StopIteration"in l?l.StopIteration:Error("StopIteration");function ua(){}ua.prototype.next=function(){throw H;};function I(a,b,c,d,f){this.a=!!b;a&&J(this,a,d);this.d=f!=undefined?f:this.c||0;if(this.a)this.d*=-1;this.h=!c}p(I,ua);I.prototype.b=null;I.prototype.c=0;I.prototype.g=false;function J(a,b,c,d){if(a.b=b)a.c=typeof c=="number"?c:a.b.nodeType!=1?0:a.a?-1:1;if(typeof d=="number")a.d=d}
+I.prototype.next=function(){var a;if(this.g){if(!this.b||this.h&&this.d==0)throw H;a=this.b;var b=this.a?-1:1;if(this.c==b){var c=this.a?a.lastChild:a.firstChild;c?J(this,c):J(this,a,b*-1)}else(c=this.a?a.previousSibling:a.nextSibling)?J(this,c):J(this,a.parentNode,b*-1);this.d+=this.c*(this.a?-1:1)}else this.g=true;a=this.b;if(!this.b)throw H;return a};
+I.prototype.splice=function(){var a=this.b,b=this.a?1:-1;if(this.c==b){this.c=b*-1;this.d+=this.c*(this.a?-1:1)}this.a=!this.a;I.prototype.next.call(this);this.a=!this.a;b=aa(arguments[0])?arguments[0]:arguments;for(var c=b.length-1;c>=0;c--)a.parentNode&&a.parentNode.insertBefore(b[c],a.nextSibling);a&&a.parentNode&&a.parentNode.removeChild(a)};function K(a,b,c,d){I.call(this,a,b,c,null,d)}p(K,I);K.prototype.next=function(){do K.j.next.call(this);while(this.c==-1);return this.b};function va(a,b){var c=E(a);if(c.defaultView&&c.defaultView.getComputedStyle)if(c=c.defaultView.getComputedStyle(a,null))return c[b]||c.getPropertyValue(b);return""}function L(a,b){return va(a,b)||(a.currentStyle?a.currentStyle[b]:null)||a.style[b]}
+function wa(a){var b=E(a),c=L(a,"position"),d=c=="fixed"||c=="absolute";for(a=a.parentNode;a&&a!=b;a=a.parentNode){c=L(a,"position");d=d&&c=="static"&&a!=b.documentElement&&a!=b.body;if(!d&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight||c=="fixed"||c=="absolute"))return a}return null};function M(a,b){return!!a&&a.nodeType==1&&(!b||a.tagName.toUpperCase()==b)}
+var xa={"class":"className",readonly:"readOnly"},ya=["checked","disabled","draggable","hidden"],za=["async","autofocus","autoplay","checked","compact","complete","controls","declare","defaultchecked","defaultselected","defer","disabled","draggable","ended","formnovalidate","hidden","indeterminate","iscontenteditable","ismap","itemscope","loop","multiple","muted","nohref","noresize","noshade","novalidate","nowrap","open","paused","pubdate","readonly","required","reversed","scoped","seamless","seeking",
+"selected","spellcheck","truespeed","willvalidate"];function Aa(a,b){if(8==a.nodeType)return null;b=b.toLowerCase();if(b=="style"){var c=a.style.cssText.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").toLowerCase();return c.charAt(c.length-1)==";"?c:c+";"}c=a.getAttributeNode(b);if(!c)return null;if(x(za,b)>=0)return"true";return c.specified?c.value:null}var Ba=["BUTTON","INPUT","OPTGROUP","OPTION","SELECT","TEXTAREA"];
+function Ca(a){var b=a.tagName.toUpperCase();if(!(x(Ba,b)>=0))return true;if(Aa(a,"disabled"))return false;if(a.parentNode&&a.parentNode.nodeType==1&&"OPTGROUP"==b||"OPTION"==b)return Ca(a.parentNode);return true}function N(a){for(a=a.parentNode;a&&a.nodeType!=1&&a.nodeType!=9&&a.nodeType!=11;)a=a.parentNode;return M(a)?a:null}function O(a,b){b=ma(String(b));return va(a,b)||Da(a,b)}
+function Da(a,b){var c=(a.currentStyle||a.style)[b];if(c!="inherit")return c!==undefined?c:null;return(c=N(a))?Da(c,b):null}function Ea(a){if(m(a.getBBox)=="function")return a.getBBox();var b;if(L(a,"display")!="none")b=new D(a.offsetWidth,a.offsetHeight);else{b=a.style;var c=b.display,d=b.visibility,f=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";var e;e=a.offsetWidth;a=a.offsetHeight;b.display=c;b.position=f;b.visibility=d;b=new D(e,a)}return b}
+function P(a,b){function c(e){if(O(e,"display")=="none")return false;e=N(e);return!e||c(e)}function d(e){var g=Ea(e);if(g.height>0&&g.width>0)return true;if(e.innerText||e.textContent)if(Fa.test(e.innerText||e.textContent))return true;return z&&na(e.childNodes,function(k){return M(k)&&d(k)})}if(!M(a))throw Error("Argument to isShown must be of type Element");if(M(a,"TITLE"))return(E(a)?E(a).parentWindow||E(a).defaultView:window)==ja;if(M(a,"OPTION")||M(a,"OPTGROUP")){var f=F(a,function(e){return M(e,
+"SELECT")});return!!f&&P(f)}if(M(a,"MAP")){if(!a.name)return false;f=E(a);f=f.evaluate?ta('/descendant::*[@usemap = "#'+a.name+'"]',f):qa(f,function(e){return M(e)&&Aa(e,"usemap")=="#"+a.name});return!!f&&P(f)}if(M(a,"AREA")){f=F(a,function(e){return M(e,"MAP")});return!!f&&P(f)}if(M(a,"INPUT")&&a.type.toLowerCase()=="hidden")return false;if(O(a,"visibility")=="hidden")return false;if(!c(a))return false;if(!b&&Ga(a)==0)return false;if(!d(a))return false;return true}
+var Ha="[\\s\\xa0"+String.fromCharCode(160)+"]+",Fa=RegExp("^"+Ha+"$");function Ga(a){var b=1,c=O(a,"opacity");if(c)b=Number(c);if(a=N(a))b*=Ga(a);return b};var Ia=["dragstart","dragexit","mouseover","mouseout"];
+function Q(a,b,c){var d=E(a),f=d?d.parentWindow||d.defaultView:window,e=new C;if(a.nodeType==1)if(a.getBoundingClientRect){var g=a.getBoundingClientRect();e.x=g.left;e.y=g.top}else{g=sa(a?new G(E(a)):B||(B=new G));var k,h=E(a);k=L(a,"position");var i=new C(0,0),t=(h?h.nodeType==9?h:E(h):document).documentElement;if(a!=t)if(a.getBoundingClientRect){k=a.getBoundingClientRect();h=sa(h?new G(E(h)):B||(B=new G));i.x=k.left+h.x;i.y=k.top+h.y}else if(h.getBoxObjectFor){k=h.getBoxObjectFor(a);h=h.getBoxObjectFor(t);
+i.x=k.screenX-h.screenX;i.y=k.screenY-h.screenY}else{var j=a;do{i.x+=j.offsetLeft;i.y+=j.offsetTop;if(j!=a){i.x+=j.clientLeft||0;i.y+=j.clientTop||0}if(z&&L(j,"position")=="fixed"){i.x+=h.body.scrollLeft;i.y+=h.body.scrollTop;break}j=j.offsetParent}while(j&&j!=a);if(z&&k=="absolute")i.y-=h.body.offsetTop;for(j=a;(j=wa(j))&&j!=h.body&&j!=t;){i.x-=j.scrollLeft;i.y-=j.scrollTop}}e.x=i.x-g.x;e.y=i.y-g.y}else{g=m(a.f)=="function";i=a;if(a.targetTouches)i=a.targetTouches[0];else if(g&&a.f().targetTouches)i=
+a.f().targetTouches[0];e.x=i.clientX;e.y=i.clientY}var n=c||{};c=(n.x||0)+e.x;e=(n.y||0)+e.y;g=n.button||0;i=n.bubble||true;k=null;if(x(Ia,b)>=0)k=n.related||null;h=!!n.alt;t=!!n.control;j=!!n.shift;n=!!n.meta;if(a.fireEvent&&d&&d.createEventObject){a=d.createEventObject();a.altKey=h;a.k=t;a.metaKey=n;a.shiftKey=j;a.clientX=c;a.clientY=e;a.button=g;a.relatedTarget=k}else{a=d.createEvent("MouseEvents");if(a.initMouseEvent)a.initMouseEvent(b,i,true,f,1,0,0,c,e,t,h,j,n,g,k);else{a.initEvent(b,i,true);
+a.shiftKey=j;a.metaKey=n;a.altKey=h;a.ctrlKey=t;a.button=g}}return a}function R(a,b,c){var d=c||{};c=d.keyCode||0;var f=d.charCode||0,e=!!d.alt,g=!!d.ctrl,k=!!d.shift;d=!!d.meta;a=E(a).createEvent("Events");a.initEvent(b,true,true);a.charCode=f;a.keyCode=c;a.altKey=e;a.ctrlKey=g;a.metaKey=d;a.shiftKey=k;return a}
+function Ja(a,b,c){var d=E(a),f=c||{};c=f.bubble!==false;var e=!!f.alt,g=!!f.control,k=!!f.shift;f=!!f.meta;if(a.fireEvent&&d&&d.createEventObject){a=d.createEventObject();a.altKey=e;a.l=g;a.metaKey=f;a.shiftKey=k}else{a=d.createEvent("HTMLEvents");a.initEvent(b,c,true);a.shiftKey=k;a.metaKey=f;a.altKey=e;a.ctrlKey=g}return a}var S={};S.click=Q;S.keydown=R;S.keypress=R;S.keyup=R;S.mousedown=Q;S.mousemove=Q;S.mouseout=Q;S.mouseover=Q;S.mouseup=Q;
+function Ka(a,b,c){c=(S[b]||Ja)(a,b,c);if(m(a.fireEvent)=="function"||ba(a.fireEvent)){try{(E(a)?E(a).parentWindow||E(a).defaultView:window).event=c}catch(d){}a=a.fireEvent("on"+b,c)}else a=a.dispatchEvent(c);return a};function T(a){var b;if(M(a,"OPTION"))b=true;else if(M(a,"INPUT")){b=a.type.toLowerCase();b=b=="checkbox"||b=="radio"}else b=false;if(!b)throw new r(15,"Element is not selectable");b="selected";var c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";b=xa[b]||b;a=a[b];a=a===undefined&&x(ya,b)>=0?false:a;return!!a}function La(a){return M(a,"SELECT")}
+function Ma(a){if(M(a,"INPUT")&&"radio"==a.type)throw new r(12,"You may not toggle a radio button");var b=!T(a);if(!Ca(a))throw new r(12,"Element is not currently enabled and may not be manipulated");if(!P(a,true))throw new r(11,"Element is not currently visible and may not be manipulated");if(M(a,"INPUT")){var c=a.type.toLowerCase();if(c=="checkbox"||c=="radio"){if(a.checked!=b){if(a.type=="radio"&&!b)throw new r(12,"You may not deselect a radio button");if(b!=T(a)){a.checked=b;Ka(a,"change")}}}else throw new r(15,
+"You may not select an unselectable input element: "+a.type);}else if(M(a,"OPTION")){c=F(a,La);if(!c.multiple&&!b)throw new r(15,"You may not deselect an option within a select that does not support multiple selections.");if(b!=T(a)){a.selected=b;Ka(c,"change")}}else throw new r(15,"You may not select an unselectable element: "+a.tagName);return T(a)};function Na(){}
+function U(a,b,c){switch(typeof b){case "string":Oa(a,b,c);break;case "number":c.push(isFinite(b)&&!isNaN(b)?b:"null");break;case "boolean":c.push(b);break;case "undefined":c.push("null");break;case "object":if(b==null){c.push("null");break}if(m(b)=="array"){var d=b.length;c.push("[");var f="";for(var e=0;e<d;e++){c.push(f);U(a,b[e],c);f=","}c.push("]");break}c.push("{");d="";for(f in b)if(Object.prototype.hasOwnProperty.call(b,f)){e=b[f];if(typeof e!="function"){c.push(d);Oa(a,f,c);c.push(":");U(a,
+e,c);d=","}}c.push("}");break;case "function":break;default:throw Error("Unknown type: "+typeof b);}}var V={'"':'\\"',"\\":"\\\\","/":"\\/","\u0008":"\\b","\u000c":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\u000b":"\\u000b"},Pa=/\uffff/.test("\uffff")?/[\\\"\x00-\x1f\x7f-\uffff]/g:/[\\\"\x00-\x1f\x7f-\xff]/g;
+function Oa(a,b,c){c.push('"',b.replace(Pa,function(d){if(d in V)return V[d];var f=d.charCodeAt(0),e="\\u";if(f<16)e+="000";else if(f<256)e+="00";else if(f<4096)e+="0";return V[d]=e+f.toString(16)}),'"')};function W(a){switch(m(a)){case "string":case "number":case "boolean":return a;case "function":return a.toString();case "array":return y(a,W);case "object":a=a;if("tagName"in a&&"nodeType"in a&&a.nodeType==1){var b={};b.ELEMENT=Qa(a);return b}if(aa(a))return y(a,W);a=da(a,function(c,d){return typeof d=="number"||o(d)});return ea(a,W);default:return null}}
+function X(a,b){if(m(a)=="array")return y(a,function(c){return X(c,b)});else if(ba(a))return"ELEMENT"in a?Ra(a.ELEMENT,b):ea(a,function(c){return X(c,b)});return a}function Sa(a){a=a||document;var b=a.$wdc_;if(!b){b=a.$wdc_={};b.i=ca()}return b}function Qa(a){var b=Sa(a.ownerDocument),c=fa(b,function(d){return d==a});if(!c){c=":wdc:"+b.i++;b[c]=a}return c}
+function Ra(a,b){a=decodeURIComponent(a);var c=b||document,d=Sa(c);if(!(a in d))throw new r(10,"Element does not exist in cache");var f=d[a];for(var e=f;e;){if(e==c.documentElement)return f;e=e.parentNode}delete d[a];throw new r(10,"Element is no longer attached to the DOM");};function Ta(a){var b=Ma;a=[a];var c;try{if(o(b))b=new Function(b);var d=X(a),f=b.apply(null,d);c={status:0,value:W(f)}}catch(e){c={status:"code"in e?e.code:13,value:{message:e.message}}}b=[];U(new Na,c,b);return b.join("")}var Y="_".split("."),Z=l;!(Y[0]in Z)&&Z.execScript&&Z.execScript("var "+Y[0]);for(var $;Y.length&&($=Y.shift());)if(!Y.length&&Ta!==undefined)Z[$]=Ta;else Z=Z[$]?Z[$]:Z[$]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
diff --git a/core/res/res/raw/webdriver_readme.txt b/core/res/res/raw/webdriver_readme.txt
new file mode 100644
index 0000000..0ab6603
--- /dev/null
+++ b/core/res/res/raw/webdriver_readme.txt
@@ -0,0 +1,37 @@
+The JavaScript files *_android.js are used in frameworks/base/core/java/android/webkit/webdriver/
+. Those files contain closure compiled JavaScript from
+http://selenium.googlecode.com. They are under the Apache 2.0 licence:
+/** @license
+Copyright 2010 WebDriver committers
+Copyright 2010 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+The licence is not included in the compiled code to minimize the size
+of JavaScript injected into web pages.
+
+Those files can be generated by doing the following:
+$svn checkout http://selenium.googlecode.com/svn/trunk/ .
+$./go //javascript/webdriver-atoms/inject:<js_fragment_name>
+
+Where <js_fragment_name> should be replaced by the actual name of the fragment to
+generate. For example to generate is_selected_android.js, execute:
+$./go //javascript/webdriver-atoms/inject:is_selected
+
+The build file for those rules is under the following:
+http://code.google.com/p/selenium/source/browse/trunk/javascript/webdriver-atoms/inject/build.desc
+Every js_fragment rule generates a JavaScript file containing the corresponding
+JavaScript code snippet.
+
+The current version of the files was generated using revision 11823.