├── prebuilt ├── ant-contrib-1.0b3.jar └── jsmockito │ ├── lib │ ├── js.jar │ ├── ant-contrib.jar │ ├── jsdoctoolkit-ant-task.jar │ ├── jquery │ │ ├── jquery.fn.js │ │ └── jquery.print.js │ └── screw-unit │ │ ├── screw.events.js │ │ ├── screw.css │ │ ├── screw.builder.js │ │ ├── screw.behaviors.js │ │ └── screw.matchers.js │ ├── AUTHORS │ ├── build.properties │ ├── ReleaseNotes.md │ ├── spec │ ├── spec_helper.js │ ├── native_types_spec.js │ ├── function_spy_spec.js │ ├── suite-dist.html │ ├── suite.html │ ├── runner.js │ └── object_spy_spec.js │ ├── LICENSE │ ├── src │ ├── native_types.js │ ├── integration.js │ ├── function.js │ └── object.js │ ├── README.md │ └── build.xml ├── res ├── values │ ├── values.xml │ └── strings.xml ├── menu │ ├── debug_menu.xml │ └── framework.xml ├── layout │ ├── webview.xml │ ├── debug_dialog.xml │ └── splash.xml └── xml │ └── config.xml ├── README.md ├── autogen ├── .classpath ├── .project └── com │ └── karura │ └── autogen │ ├── BuildConfig.java │ ├── FunctionType.java │ ├── utils │ ├── SourceBuffer.java │ └── StringUtils.java │ ├── codegen │ ├── FrameworkGenerator.java │ └── AbsCodeGenerator.java │ └── Main.java ├── .gitignore ├── project.properties ├── LICENCE-APACHE2.0 ├── proguard-project.txt ├── src └── com │ └── karura │ └── framework │ ├── TaskCallback.java │ ├── config │ ├── XMLNode.java │ ├── LoaderFactory.java │ ├── DalvikConfigLoader.java │ ├── JavaConfigLoader.java │ ├── ConfigLoader.java │ └── ConfigStore.java │ ├── annotations │ ├── Param.java │ ├── JavascriptModule.java │ ├── Events.java │ ├── Params.java │ ├── Synchronous.java │ ├── Asynchronous.java │ ├── Event.java │ ├── SupportJavascriptInterface.java │ ├── ExportToJs.java │ ├── MinimumPlatformVersion.java │ └── Description.java │ ├── plugins │ ├── file │ │ ├── EncodingException.java │ │ ├── FileExistsException.java │ │ ├── TypeMismatchException.java │ │ ├── InvalidModificationException.java │ │ └── NoModificationAllowedException.java │ ├── PluginConstants.java │ ├── Logger.java │ ├── utils │ │ └── DirectoryManager.java │ └── Device.java │ ├── utils │ ├── TypeUtils.java │ ├── MsgQueue.java │ ├── UrlUtils.java │ ├── PackageInspector.java │ ├── Reader.java │ ├── JsHelper.java │ └── StringUtils.java │ ├── Constants.java │ ├── FrameworkConfig.java │ ├── KaruraApp.java │ └── ui │ ├── webview │ ├── KaruraWebChromeClient.java │ └── KaruraWebViewClient.java │ └── SplashActivity.java ├── AndroidManifest.xml ├── assets └── karura │ └── js │ └── framework │ ├── namespace.js │ ├── scripts.js │ ├── dispatcher.js │ └── object_map.js └── custom_rules.xml /prebuilt/ant-contrib-1.0b3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karuradev/karura/HEAD/prebuilt/ant-contrib-1.0b3.jar -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/js.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karuradev/karura/HEAD/prebuilt/jsmockito/lib/js.jar -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/ant-contrib.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karuradev/karura/HEAD/prebuilt/jsmockito/lib/ant-contrib.jar -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/jsdoctoolkit-ant-task.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karuradev/karura/HEAD/prebuilt/jsmockito/lib/jsdoctoolkit-ant-task.jar -------------------------------------------------------------------------------- /res/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20sp 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | karura 2 | ====== 3 | 4 | A open source framework for Hybrid application development on Android 5 | 6 | ##Our book is available from Amazon.com. 7 | ##http://www.amazon.com/Building-Hybrid-Android-Apps-JavaScript/dp/1449361919/ 8 | -------------------------------------------------------------------------------- /res/menu/debug_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /res/menu/framework.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /autogen/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/AUTHORS: -------------------------------------------------------------------------------- 1 | Primary author: 2 | 3 | Chris Leishman 4 | 5 | 6 | And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS -- 7 | people who have helped directly or indirectly to make JsMockito much better 8 | (in alphabetic order): 9 | 10 | Volodymyr Mykhailyk 11 | EleotleCram 12 | -------------------------------------------------------------------------------- /autogen/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | karura-gen 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | lint.xml 15 | build.log 16 | tools 17 | # Local configuration file (sdk path, etc) 18 | local.properties 19 | 20 | # Eclipse project files 21 | .metadata 22 | .settings 23 | 24 | # Misc 25 | *~ 26 | *.iml 27 | 28 | # IntelliJ 29 | .idea 30 | 31 | # SASS 32 | .sass-cache 33 | 34 | -------------------------------------------------------------------------------- /res/layout/webview.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/build.properties: -------------------------------------------------------------------------------- 1 | # Project info 2 | NAME = jsmockito 3 | VERSION = 1.0.4 4 | NAME_V = ${NAME}-${VERSION} 5 | 6 | # Third-party libraries and applications 7 | LIB_DIR = ${basedir}/lib 8 | TOOLS_DIR = ${basedir}/tools 9 | 10 | # Documentation output directory 11 | DOC_DIR = ${basedir}/doc 12 | API_DIR = ${DOC_DIR}/api 13 | 14 | # Framework source code 15 | SRC_DIR = ${basedir}/src 16 | 17 | # Build output directory 18 | BUILD_DIR = ${basedir}/build 19 | DIST_DIR = ${basedir}/dist 20 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Alert 5 | Confirm 6 | Loading file.. 7 | Karura Framework 8 | Geoxies, LLC. 9 | Framework could not be initialzied. 10 | 11 | -------------------------------------------------------------------------------- /res/layout/debug_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | android.library=true 16 | -------------------------------------------------------------------------------- /LICENCE-APACHE2.0: -------------------------------------------------------------------------------- 1 | Licensed to the Apache Software Foundation (ASF) under one 2 | or more contributor license agreements. See the NOTICE file 3 | distributed with this work for additional information 4 | regarding copyright ownership. The ASF licenses this file 5 | to you under the Apache License, Version 2.0 (the 6 | "License"); you may not use this file except in compliance 7 | with the License. You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, 12 | software distributed under the License is distributed on an 13 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | KIND, either express or implied. See the License for the 15 | specific language governing permissions and limitations 16 | under the License. -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/jquery/jquery.fn.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $.fn.fn = function() { 3 | var self = this; 4 | var extension = arguments[0], name = arguments[0]; 5 | if (typeof name == "string") { 6 | return apply(self, name, $.makeArray(arguments).slice(1, arguments.length)); 7 | } else { 8 | $.each(extension, function(key, value) { 9 | define(self, key, value); 10 | }); 11 | return self; 12 | } 13 | } 14 | function define(self, name, fn) { 15 | self.data(namespacedName(name), fn); 16 | }; 17 | function apply(self, name, args) { 18 | var result; 19 | self.each(function(i, item) { 20 | var fn = $(item).data(namespacedName(name)); 21 | if (fn) result = fn.apply(item, args) 22 | else throw(name + " is not defined"); 23 | }); 24 | return result; 25 | }; 26 | function namespacedName(name) { 27 | return 'fn.' + name; 28 | } 29 | })(jQuery); -------------------------------------------------------------------------------- /autogen/com/karura/autogen/BuildConfig.java: -------------------------------------------------------------------------------- 1 | package com.karura.autogen; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | public class BuildConfig { 25 | public static boolean DEBUG = true; 26 | } 27 | -------------------------------------------------------------------------------- /src/com/karura/framework/TaskCallback.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | public interface TaskCallback { 25 | public void done(T result); 26 | public void error(Exception e); 27 | } 28 | -------------------------------------------------------------------------------- /src/com/karura/framework/config/XMLNode.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.config; 2 | 3 | 4 | /** 5 | 6 | ============== GPL License ============== 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | 21 | ============== Commercial License============== 22 | https://github.com/karuradev/licenses/blob/master/toc.txt 23 | */ 24 | 25 | public interface XMLNode { 26 | public String getAttributeValue(String attr); 27 | public String getName(); 28 | public boolean getAttributeBooleanValue(String attr, boolean defaultVal); 29 | } 30 | -------------------------------------------------------------------------------- /autogen/com/karura/autogen/FunctionType.java: -------------------------------------------------------------------------------- 1 | package com.karura.autogen; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | /* 25 | * Used to keep track of function types which will be exported from the 26 | * native layer 27 | */ 28 | public enum FunctionType { 29 | SYNC_FN(1), ASYNC_FN(2), EVENT(3); 30 | int type; 31 | 32 | FunctionType(int type) { 33 | this.type = type; 34 | } 35 | } -------------------------------------------------------------------------------- /prebuilt/jsmockito/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | Changed in 1.0.4 (2011-08-16) 2 | ============================= 3 | 4 | Various bugfixes: 5 | - An issue where last stubbing was not preferred 6 | (reported by Volodymyr Mykhailyk, 7 | https://github.com/chrisleishman/jsmockito/issues/1) 8 | - An issue where mocked Arrays could not be validated with bulk validators 9 | (reported by 'HitmanInWis', 10 | https://github.com/chrisleishman/jsmockito/issues/5) 11 | - An issue where 'thenReturn' and 'thenThrow' stubs where not chaining 12 | (reported by 'HitmanInWis', 13 | https://github.com/chrisleishman/jsmockito/issues/6) 14 | 15 | Changed in 1.0.3 (2011-02-21) 16 | ============================= 17 | 18 | Added jSpec integration and support for spying on constructors (courtesy of Ben Cherry https://github.com/bcherry). 19 | 20 | Changed in 1.0.2 (2010-01-21) 21 | ============================= 22 | 23 | Added additional documentation and the verifyNoMoreInteractions(mock) feature 24 | 25 | Changed in 1.0.1 (2009-09-11) 26 | ============================= 27 | 28 | Bugfix: Fixed IE issue affecting verification failure messages 29 | 30 | Changed in 1.0.0 (2009-09-10) 31 | ============================= 32 | 33 | Initial release 34 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Param.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.Retention; 26 | import java.lang.annotation.RetentionPolicy; 27 | 28 | @Documented 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface Param { 31 | String name(); 32 | String description(); 33 | } 34 | -------------------------------------------------------------------------------- /src/com/karura/framework/config/LoaderFactory.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.config; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import android.content.Context; 25 | 26 | public class LoaderFactory { 27 | public static ConfigLoader getLoader(boolean isAndroid, Object context){ 28 | if (isAndroid){ 29 | return new DalvikConfigLoader((Context)context); 30 | } 31 | return new JavaConfigLoader((String)context); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/spec_helper.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | JsHamcrest.Integration.screwunit(); 3 | JsMockito.Integration.screwunit(); 4 | 5 | Screw.Matchers.throwsMessage = function(exceptionText) { 6 | return new JsHamcrest.SimpleMatcher({ 7 | matches: function(actualFunction) { 8 | try { 9 | actualFunction(); 10 | } catch (e) { 11 | var message = e.message || e; 12 | if (JsHamcrest.Matchers.equalTo(exceptionText).matches(message)) { 13 | return true; 14 | } else { 15 | throw e; 16 | } 17 | } 18 | return false; 19 | }, 20 | 21 | describeTo: function(description) { 22 | description.append('throws "').append(exceptionText).append('"'); 23 | } 24 | }); 25 | } 26 | 27 | var MyObject = function() {}; 28 | MyObject.prototype = { 29 | greeting: function() { return "hello" }, 30 | farewell: function() { return "goodbye" } 31 | }; 32 | 33 | var MyUnwritableObject = function() {}; 34 | 35 | Object.defineProperties(MyUnwritableObject.prototype, { 36 | greeting: { enumerable: false, writable: false, value: function() { return "hello" } }, 37 | farewell: { enumerable: true, writable: false, value: function() { return "goodbye" } } 38 | }); 39 | -------------------------------------------------------------------------------- /res/layout/splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 22 | 23 | 24 | 32 | 33 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/JavascriptModule.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.Retention; 26 | import java.lang.annotation.RetentionPolicy; 27 | 28 | @Documented 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface JavascriptModule { 31 | String configElementName() default ""; 32 | Class [] exportedClasses() default {}; 33 | } 34 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Events.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.TYPE }) 33 | public @interface Events { 34 | Event[] value(); 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Params.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.METHOD }) 33 | public @interface Params { 34 | Param[] value(); 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Synchronous.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.METHOD }) 33 | public @interface Synchronous { 34 | String retVal (); 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Asynchronous.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.METHOD }) 33 | public @interface Asynchronous { 34 | String retVal(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Event.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.TYPE }) 33 | public @interface Event { 34 | String name(); 35 | 36 | Class[] args(); 37 | } 38 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/SupportJavascriptInterface.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.METHOD }) 33 | public @interface SupportJavascriptInterface { 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/ExportToJs.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.FIELD, ElementType.TYPE}) 33 | public @interface ExportToJs { 34 | Class [] classes() default {}; 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/MinimumPlatformVersion.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.METHOD, ElementType.TYPE}) 33 | public @interface MinimumPlatformVersion { 34 | double value(); 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/annotations/Description.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.annotations; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.lang.annotation.Documented; 25 | import java.lang.annotation.ElementType; 26 | import java.lang.annotation.Retention; 27 | import java.lang.annotation.RetentionPolicy; 28 | import java.lang.annotation.Target; 29 | 30 | @Documented 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) 33 | public @interface Description { 34 | String value(); 35 | } 36 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/file/EncodingException.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | package com.karura.framework.plugins.file; 27 | 28 | public class EncodingException extends Exception { 29 | 30 | /** 31 | * 32 | */ 33 | private static final long serialVersionUID = 6845912047006616871L; 34 | 35 | public EncodingException(String message) { 36 | super(message); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/file/FileExistsException.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.plugins.file; 28 | 29 | public class FileExistsException extends Exception { 30 | 31 | /** 32 | * 33 | */ 34 | private static final long serialVersionUID = -3637384283286696336L; 35 | 36 | public FileExistsException(String msg) { 37 | super(msg); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/file/TypeMismatchException.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.plugins.file; 28 | 29 | public class TypeMismatchException extends Exception { 30 | 31 | /** 32 | * 33 | */ 34 | private static final long serialVersionUID = -4491002311613704494L; 35 | 36 | public TypeMismatchException(String message) { 37 | super(message); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/file/InvalidModificationException.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.plugins.file; 28 | 29 | public class InvalidModificationException extends Exception { 30 | 31 | /** 32 | * 33 | */ 34 | private static final long serialVersionUID = -3682935446969960806L; 35 | 36 | public InvalidModificationException(String message) { 37 | super(message); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/file/NoModificationAllowedException.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.plugins.file; 28 | 29 | public class NoModificationAllowedException extends Exception { 30 | 31 | /** 32 | * 33 | */ 34 | private static final long serialVersionUID = 4826714754209560483L; 35 | 36 | public NoModificationAllowedException(String message) { 37 | super(message); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/karura/framework/utils/TypeUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | 23 | package com.karura.framework.utils; 24 | 25 | import java.util.Arrays; 26 | import java.util.HashSet; 27 | import java.util.Set; 28 | 29 | public class TypeUtils { 30 | 31 | @SuppressWarnings("unchecked") 32 | private static final Set> WRAPPER_TYPES = new HashSet>(Arrays.asList(Boolean.class, Character.class, Byte.class, 33 | Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class)); 34 | 35 | public static boolean isWrapperType(Class clazz) { 36 | return WRAPPER_TYPES.contains(clazz); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/com/karura/framework/Constants.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | /** 25 | * Holds the constants used all over the framework 26 | * 27 | * @author nitin 28 | * 29 | */ 30 | public interface Constants { 31 | 32 | /** 33 | * This is the id for an invalid object 34 | */ 35 | public static final int INVALID_RECEIVER_ID = -1; 36 | /** 37 | * This is the id for the framework, APIs directed to this Id will be processed by the framework in either direction 38 | */ 39 | public static final int FRAMEWORK_RECEIVER_ID = 0; 40 | 41 | /** 42 | * Minimum duration for which the Splash Screen needs to be displayed.s 43 | */ 44 | int MINIMUM_SPLASH_DURATION = 3000; 45 | } 46 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/screw-unit/screw.events.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(Screw) 3 | .bind('loaded', function() { 4 | $('.describe, .it') 5 | .click(function() { 6 | document.location = location.href.split('?')[0] + '?' + $(this).fn('selector'); 7 | return false; 8 | }) 9 | .focus(function() { 10 | return $(this).addClass('focused'); 11 | }) 12 | .bind('scroll', function() { 13 | document.body.scrollTop = $(this).offset().top; 14 | }); 15 | 16 | $('.it') 17 | .bind('enqueued', function() { 18 | $(this).addClass('enqueued'); 19 | }) 20 | .bind('running', function() { 21 | $(this).addClass('running'); 22 | }) 23 | .bind('passed', function() { 24 | $(this).addClass('passed'); 25 | }) 26 | .bind('failed', function(e, reason) { 27 | $(this) 28 | .addClass('failed') 29 | .append($('

').text(reason.toString())); 30 | 31 | var file = reason.fileName || reason.sourceURL; 32 | var line = reason.lineNumber || reason.line; 33 | if (file || line) { 34 | $(this).append($('

').text('line ' + line + ', ' + file)); 35 | } 36 | }) 37 | }) 38 | .bind('before', function() { 39 | Screw.suite_start_time = new Date(); 40 | $('.status').text('Running...'); 41 | }) 42 | .bind('after', function() { 43 | $('.status').fn('display') 44 | }) 45 | })(jQuery); -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/native_types_spec.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | Screw.Unit(function() { 3 | describe('JsMockito mocking of native types', function() { 4 | JsMockito.each(JsMockito.nativeTypes, function(ntype, name) { 5 | describe('#' + name, function() { 6 | JsMockito.each(ntype.methods, function(methodName) { 7 | describe("native object", function() { 8 | it("should have a " + methodName + " method", function() { 9 | var nObj = new ntype.type(); 10 | assertThat(nObj[methodName], typeOf("function")); 11 | }); 12 | }); 13 | 14 | describe("class mock", function() { 15 | it("should have a " + methodName + " mock method", function() { 16 | var mockNObj = mock(ntype.type); 17 | assertThat(JsMockito.isMock(mockNObj[methodName]), equalTo(true)); 18 | }); 19 | }); 20 | }); 21 | }); 22 | }); 23 | 24 | describe('bulk verification of Array class', function() { 25 | var mockArray; 26 | before(function() { 27 | mockArray = mock(Array); 28 | }); 29 | 30 | it("should verifyZeroInteractions when there are none", function() { 31 | verifyZeroInteractions(mockArray); 32 | }); 33 | 34 | it("should fail to verifyZeroInterations when there are", function() { 35 | mockArray.push(5); 36 | assertThat(function() { 37 | verifyZeroInteractions(mockArray); 38 | }, throwsMessage('Never wanted but invoked: obj.push()')); 39 | }); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /res/xml/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Chris Leishman 2 | 3 | https://github.com/chrisleishman/jsmockito 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of JsMockito nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/function_spy_spec.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | Screw.Unit(function() { 3 | describe('JsMockito function spy', function() { 4 | var mockFunc; 5 | var proxyMock; 6 | before(function() { 7 | mockFunc = mockFunction(); 8 | proxyMock = spy(mockFunc); 9 | }); 10 | 11 | describe("when invoked", function() { 12 | var scope; 13 | before(function() { 14 | scope = {}; 15 | proxyMock.call(scope, 'foo', 42); 16 | }); 17 | 18 | it("should invoke proxied function", function() { 19 | verify(mockFunc)('foo', 42); 20 | }); 21 | it("should invoke proxied function with same scope", function() { 22 | verify(mockFunc).call(scope, 'foo'); 23 | }); 24 | }); 25 | 26 | describe("when stubbed", function() { 27 | before(function() { 28 | when(proxyMock)('bar').thenReturn(99); 29 | }); 30 | 31 | describe("when invoked with arguments matching stub", function() { 32 | var result; 33 | before(function() { 34 | result = proxyMock('bar'); 35 | }); 36 | 37 | it("should return result of stub", function() { 38 | assertThat(result, equalTo(99)); 39 | }); 40 | 41 | it("should not invoke proxied function", function() { 42 | verifyZeroInteractions(mockFunc); 43 | }); 44 | }); 45 | 46 | describe("when invoked with arguments not matching stub", function() { 47 | before(function() { 48 | proxyMock('foo'); 49 | }); 50 | 51 | it("should invoke the proxied function", function() { 52 | verify(mockFunc)('foo'); 53 | }); 54 | }); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/suite-dist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JsMockito Test Suite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/src/native_types.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | JsMockito.nativeTypes = { 3 | 'Array': { 4 | type: Array, 5 | methods: [ 6 | 'concat', 'join', 'pop', 'push', 'reverse', 'shift', 'slice', 'sort', 7 | 'splice', 'toString', 'unshift', 'valueOf' 8 | ] 9 | }, 10 | 'Boolean': { 11 | type: Boolean, 12 | methods: [ 13 | 'toString', 'valueOf' 14 | ] 15 | }, 16 | 'Date': { 17 | type: Date, 18 | methods: [ 19 | 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 20 | 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 21 | 'getUTCDate', 'getUTCDay', 'getUTCMonth', 'getUTCFullYear', 22 | 'getUTCHours', 'getUTCMinutes', 'getUTCSeconds', 'getUTCMilliseconds', 23 | 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 24 | 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 25 | 'setUTCMonth', 'setUTCFullYear', 'setUTCHours', 'setUTCMinutes', 26 | 'setUTCSeconds', 'setUTCMilliseconds', 'setYear', 'toDateString', 27 | 'toGMTString', 'toLocaleDateString', 'toLocaleTimeString', 28 | 'toLocaleString', 'toString', 'toTimeString', 'toUTCString', 29 | 'valueOf' 30 | ] 31 | }, 32 | 'Number': { 33 | type: Number, 34 | methods: [ 35 | 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 36 | 'valueOf' 37 | ] 38 | }, 39 | 'String': { 40 | type: String, 41 | methods: [ 42 | 'anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 43 | 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 44 | 'lastIndexOf', 'link', 'match', 'replace', 'search', 'slice', 'small', 45 | 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLowerCase', 46 | 'toUpperCase', 'valueOf' 47 | ] 48 | }, 49 | 'RegExp': { 50 | type: RegExp, 51 | methods: [ 52 | 'compile', 'exec', 'test' 53 | ] 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /src/com/karura/framework/FrameworkConfig.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import com.karura.framework.utils.StringUtils; 25 | 26 | public class FrameworkConfig { 27 | 28 | /** 29 | * Name of the framework. Some of these values are read from config.xml located in the res folder. 30 | * You can override these values if you like for your applications, by specifying a custom in config.xml 31 | */ 32 | public static String FRAMEWORK_NAME = "karura"; 33 | 34 | /** 35 | * Name of the framework file which will be generated from plugins. Will be overriden by the value 36 | * defined in the config.xml file 37 | */ 38 | public static String FRAMEWORK_JS_FILENAME = FRAMEWORK_NAME + ".js"; 39 | 40 | /** 41 | * Framework version, can be overridden using config.xml 42 | */ 43 | public static String FRAMEWORK_VERSION = "1.0"; 44 | 45 | /** 46 | * The binding name for framework plugin manager in the javascript environment 47 | */ 48 | public static String FRAMEWORK_JS_HANDLE = "_" + FRAMEWORK_NAME + "_plugins"; 49 | 50 | /** 51 | * 52 | */ 53 | public static String FRAMEWORK_JS_CLASS_NAME = StringUtils.capitalize(FRAMEWORK_NAME); 54 | } 55 | -------------------------------------------------------------------------------- /src/com/karura/framework/utils/MsgQueue.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | 23 | package com.karura.framework.utils; 24 | 25 | import java.util.HashMap; 26 | 27 | import android.annotation.SuppressLint; 28 | import android.util.Pair; 29 | 30 | @SuppressLint("UseSparseArrays") 31 | public class MsgQueue { 32 | 33 | private static final HashMap> queue = new HashMap>(); 34 | private static final int MAX_HANDLE_ID = 0x7fffffff; 35 | private static Integer nextId = 1; 36 | 37 | public String get(int id) { 38 | Pair p = queue.remove(id); 39 | return p.second; 40 | } 41 | 42 | public int add(String javascript, String receiverId) { 43 | synchronized (nextId) { 44 | int curId = nextId; 45 | nextId = ++nextId % MAX_HANDLE_ID; 46 | queue.put(curId, Pair.create(receiverId, javascript)); 47 | return curId; 48 | } 49 | } 50 | 51 | public void releaseReceiver(String receiver) { 52 | for (Integer key : queue.keySet()) { 53 | Pair p = queue.get(key); 54 | if (p.first.compareTo(receiver) == 0) { 55 | queue.remove(key); 56 | } 57 | } 58 | } 59 | 60 | public void clear(){ 61 | queue.clear(); 62 | } 63 | } -------------------------------------------------------------------------------- /src/com/karura/framework/utils/UrlUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | 23 | package com.karura.framework.utils; 24 | 25 | import java.util.Iterator; 26 | 27 | import org.json.JSONException; 28 | import org.json.JSONObject; 29 | 30 | import android.net.Uri.Builder; 31 | import android.net.UrlQuerySanitizer; 32 | 33 | public class UrlUtils { 34 | 35 | public static UrlQuerySanitizer sanitizeQuery(String query, String[] parameters) { 36 | UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(); 37 | 38 | sanitizer.registerParameters(parameters, UrlQuerySanitizer.getSpaceLegal()); 39 | sanitizer.parseUrl(query); 40 | return sanitizer; 41 | } 42 | 43 | public static String jsonToQuery(String jsonString, String scheme, String authority) throws JSONException { 44 | Builder builder = new Builder(); 45 | builder.scheme(scheme); 46 | builder.authority(authority); 47 | 48 | JSONObject json = new JSONObject(jsonString.trim()); 49 | Iterator keys = json.keys(); 50 | String key = null; 51 | String value = null; 52 | while (keys.hasNext()) { 53 | key = String.valueOf(keys.next()); 54 | value = String.valueOf(json.get(key)); 55 | builder.appendQueryParameter(key, value); 56 | } 57 | return builder.build().toString(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/suite.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JsMockito Test Suite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/com/karura/framework/KaruraApp.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import android.app.Application; 25 | import com.karura.framework.config.ConfigStore; 26 | 27 | /** 28 | * Base application class for your application. The application class is a 29 | * holder for all global data that you might want to persist in your application 30 | * 31 | * @author nitin 32 | * 33 | */ 34 | public class KaruraApp extends Application { 35 | 36 | private static KaruraApp appInstance; 37 | private ConfigStore appConfig; 38 | private PluginManager pluginManager; 39 | 40 | /** 41 | * Store the singleton instance of the application for future access and 42 | * reference 43 | */ 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | appInstance = this; 48 | } 49 | 50 | public static KaruraApp getApp() { 51 | return appInstance; 52 | } 53 | 54 | public void setAppConfig(ConfigStore appConfig) { 55 | this.appConfig = appConfig; 56 | } 57 | 58 | public ConfigStore getAppConfig() { 59 | return appConfig; 60 | } 61 | 62 | public PluginManager getPluginManager() { 63 | return pluginManager; 64 | } 65 | 66 | public void setPluginManager(PluginManager pluginManager) { 67 | this.pluginManager = pluginManager; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/PluginConstants.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.plugins; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import com.karura.framework.annotations.ExportToJs; 25 | 26 | public interface PluginConstants { 27 | 28 | static final String ON_RESOLVE_ACTION = "resolve"; 29 | static final String ON_PROGRESS_ACTION = "progress"; 30 | static final String ON_REJECT_ACTION = "reject"; 31 | 32 | static final String RESPONSE_PAYLOAD = "data"; 33 | static final String EVENT_PAYLOAD = "data"; 34 | 35 | public static final int INVALID_TIMEOUT = -1; 36 | 37 | @ExportToJs 38 | public static final int SUCCESS = 0; 39 | @ExportToJs 40 | public static final int ERR_UNKNOWN = 1; 41 | @ExportToJs 42 | public static final int ERR_INVALID_ARGUMENT = 2; 43 | @ExportToJs 44 | public static final int ERR_TIMEOUT = 3; 45 | @ExportToJs 46 | public static final int ERR_IO = 4; 47 | @ExportToJs 48 | public static final int ERR_NOT_SUPPORTED = 5; 49 | @ExportToJs 50 | public static final int ERR_INVALID_ARG = 6; 51 | @ExportToJs 52 | public static final int ERR_EMPTY_RESULT = 7; 53 | @ExportToJs 54 | public static final int ERR_INVALID_JSON = 8; 55 | @ExportToJs 56 | public static final int ERR_RECORD_NOT_FOUND = 9; 57 | @ExportToJs 58 | public static final int ERR_PERMISSION_DENIED = 20; 59 | } 60 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/screw-unit/screw.css: -------------------------------------------------------------------------------- 1 | html { 2 | padding: 0.5em; 3 | font-family: Georgia, serif; 4 | background: #EDEBD5; 5 | } 6 | 7 | li { 8 | list-style-type: none; 9 | } 10 | 11 | .focused { 12 | background-color: #F4F2E4; 13 | } 14 | 15 | .focused * { 16 | opacity: 1.0; 17 | } 18 | 19 | h1, h2, p { 20 | opacity: 0.4; 21 | } 22 | 23 | .describes { 24 | padding-left: 0; 25 | } 26 | 27 | .describes h1 { 28 | font-size: 1.1em; 29 | color: #877C21; 30 | line-height: 1.8em; 31 | margin: 0pt 0pt 0.6em; 32 | border-bottom: 1px solid transparent; 33 | } 34 | 35 | .describes h1:hover { 36 | cursor: pointer; 37 | color: #000; 38 | background-color: #F4F2E4; 39 | border-bottom: 1px solid #9A8E51; 40 | } 41 | 42 | .describes .describe { 43 | margin-left: 0.6em; 44 | padding-left: 0.6em; 45 | border: 1px dashed grey; 46 | } 47 | 48 | .describes .describe .its {} 49 | 50 | .describes .describe .its .it { 51 | list-style-type: lower-roman; 52 | list-style-position: outside; 53 | } 54 | 55 | .describes .describe .its .it h2 { 56 | font-weight: normal; 57 | font-style: italic; 58 | padding-left: 0.5em; 59 | font-size: 1.0em; 60 | color: #877C21; 61 | line-height: 1.8em; 62 | margin: 0 0 0.5em; 63 | border-bottom: 1px solid transparent; 64 | } 65 | 66 | .describes .describe .its .it.enqueued h2 { 67 | background-color: #CC6600; 68 | color: white !important; 69 | } 70 | 71 | .describes .describe .its .it.passed h2 { 72 | background-color: #5A753D; 73 | color: white !important; 74 | } 75 | 76 | .describes .describe .its .it.failed h2 { 77 | background-color: #993300; 78 | color: white !important; 79 | } 80 | 81 | .describes .describe .its .it.failed p { 82 | margin-left: 1em; 83 | color: #993300; 84 | } 85 | 86 | .describes .describe .its .it h2:hover { 87 | cursor: pointer; 88 | color: #000 !important; 89 | border-bottom: 1px solid #9A8E51; 90 | } -------------------------------------------------------------------------------- /assets/karura/js/framework/namespace.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | /* 23 | * The undefined at the end of the function parameter list creates a local undefined in case someone redefines undefined 24 | * somewhere in the scope chain. 25 | * Also provides a faster lookup since undefined is a global property, so the scope chain traversal is reduced. 26 | */ 27 | function defineNamespace(namespace, undefined) { 28 | 'use strict'; 29 | 30 | namespace = namespace || {}; 31 | 32 | namespace.add = function(exportName, objectForExport) { 33 | if (exportName.length === 0) { 34 | debug.info('[Namespace] An empty export was ignored'); 35 | return namespace; 36 | } 37 | 38 | var rexp = /^([\$\_a-z][\$\_a-z\d]*\.?)+$/i; 39 | 40 | // if not a valid export name then we cannot process this request 41 | if (!exportName.match(rexp)) { 42 | debug.error('[Namespace] namespace was not extended because the export name was invalid.'); 43 | return; 44 | } 45 | 46 | var names = exportName.split('.'); 47 | var _namespace = namespace; 48 | 49 | for (var i = 0; i < names.length; i++) { 50 | var entry = names[i]; 51 | if (!(entry in _namespace)) { 52 | debug.info('[Namespace] : Adding a new object of name ' + entry); 53 | if (objectForExport === null){ 54 | _namespace[entry] = Object.create(null); 55 | }else{ 56 | _namespace[entry] = objectForExport; 57 | } 58 | } 59 | _namespace = _namespace[entry]; 60 | } 61 | return _namespace; 62 | }; 63 | return namespace; 64 | } 65 | 66 | //add the exports namespace 67 | window.exports = defineNamespace(window.exports); 68 | window.globals = defineNamespace(window.globals); 69 | -------------------------------------------------------------------------------- /autogen/com/karura/autogen/utils/SourceBuffer.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | package com.karura.autogen.utils; 23 | 24 | import java.util.Arrays; 25 | 26 | import com.karura.autogen.BuildConfig; 27 | 28 | public class SourceBuffer { 29 | 30 | StringBuilder sb = new StringBuilder(); 31 | int indent = 0; 32 | 33 | public void reset() { 34 | sb.replace(0, sb.length(), ""); 35 | } 36 | 37 | public String toString() { 38 | return sb.toString(); 39 | } 40 | 41 | public void addLine(String line) { 42 | String lines[] = line.split("\n"); 43 | for(int index = 0; index < lines.length; index++){ 44 | sb.append(getSpaceInFront() + lines[index]); 45 | if (BuildConfig.DEBUG){ 46 | sb.append("\n"); 47 | } 48 | } 49 | } 50 | 51 | public void sB(String line) { 52 | sb.append(getSpaceInFront() + line + "{"); 53 | if (BuildConfig.DEBUG){ 54 | sb.append("\n"); 55 | } 56 | indent++; 57 | } 58 | 59 | public void eB() { 60 | indent--; 61 | sb.append(getSpaceInFront() + "}"); 62 | if (BuildConfig.DEBUG){ 63 | sb.append("\n"); 64 | } 65 | } 66 | 67 | public void eBWithComma() { 68 | indent--; 69 | sb.append(getSpaceInFront() + "},"); 70 | 71 | if (BuildConfig.DEBUG){ 72 | sb.append("\n"); 73 | sb.append("\n"); 74 | } 75 | } 76 | 77 | public void eBwithSemi() { 78 | indent--; 79 | sb.append(getSpaceInFront() + "};"); 80 | if (BuildConfig.DEBUG){ 81 | sb.append("\n"); 82 | } 83 | } 84 | 85 | public String getSpaceInFront() { 86 | if (!BuildConfig.DEBUG){ 87 | return ""; 88 | } 89 | char[] space = new char[indent * 4]; 90 | Arrays.fill(space, ' '); 91 | return new String(space); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/screw-unit/screw.builder.js: -------------------------------------------------------------------------------- 1 | var Screw = (function($) { 2 | var screw = { 3 | Unit: function(fn) { 4 | var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1]; 5 | var fn = new Function("matchers", "specifications", 6 | "with (specifications) { with (matchers) { " + contents + " } }" 7 | ); 8 | 9 | $(Screw).queue(function() { 10 | Screw.Specifications.context.push($('body > .describe')); 11 | fn.call(this, Screw.Matchers, Screw.Specifications); 12 | Screw.Specifications.context.pop(); 13 | $(this).dequeue(); 14 | }); 15 | }, 16 | 17 | Specifications: { 18 | context: [], 19 | 20 | describe: function(name, fn) { 21 | var describe = $('
  • ') 22 | .append($('

    ').text(name)) 23 | .append('
      ') 24 | .append('
        ') 25 | .append('
          ') 26 | .append('
            '); 27 | 28 | this.context.push(describe); 29 | fn.call(); 30 | this.context.pop(); 31 | 32 | this.context[this.context.length-1] 33 | .children('.describes') 34 | .append(describe); 35 | }, 36 | 37 | it: function(name, fn) { 38 | var it = $('
          1. ') 39 | .append($('

            ').text(name)) 40 | .data('screwunit.run', fn); 41 | 42 | this.context[this.context.length-1] 43 | .children('.its') 44 | .append(it); 45 | }, 46 | 47 | before: function(fn) { 48 | var before = $('
          2. ') 49 | .data('screwunit.run', fn); 50 | 51 | this.context[this.context.length-1] 52 | .children('.befores') 53 | .append(before); 54 | }, 55 | 56 | after: function(fn) { 57 | var after = $('
          3. ') 58 | .data('screwunit.run', fn); 59 | 60 | this.context[this.context.length-1] 61 | .children('.afters') 62 | .append(after); 63 | } 64 | } 65 | }; 66 | 67 | $(screw).queue(function() { $(screw).trigger('loading') }); 68 | 69 | $(window).load(function(){ 70 | $('
            ') 71 | .append('

            ') 72 | .append('
              ') 73 | .append('
                ') 74 | .append('
                  ') 75 | .appendTo('body'); 76 | 77 | $(screw).dequeue(); 78 | $(screw).trigger('loaded'); 79 | }); 80 | 81 | return screw; 82 | })(jQuery); -------------------------------------------------------------------------------- /prebuilt/jsmockito/src/integration.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | 3 | /** 4 | * Verifiers 5 | * @namespace 6 | */ 7 | JsMockito.Integration = { 8 | /** 9 | * Import the public JsMockito API into the specified object (namespace) 10 | * 11 | * @param {object} target An object (namespace) that will be populated with 12 | * the functions from the public JsMockito API 13 | */ 14 | importTo: function(target) { 15 | JsMockito.each(JsMockito._export, function(exported) { 16 | target[exported] = JsMockito[exported]; 17 | }); 18 | 19 | JsMockito.each(JsMockito.Verifiers._export, function(exported) { 20 | target[exported] = JsMockito.Verifiers[exported]; 21 | }); 22 | }, 23 | 24 | /** 25 | * Make the public JsMockito API available in Screw.Unit 26 | * @see JsMockito.Integration.importTo(Screw.Matchers) 27 | */ 28 | screwunit: function() { 29 | JsMockito.Integration.importTo(Screw.Matchers); 30 | }, 31 | 32 | /** 33 | * Make the public JsMockito API available to JsTestDriver 34 | * @see JsMockito.Integration.importTo(window) 35 | */ 36 | JsTestDriver: function() { 37 | JsMockito.Integration.importTo(window); 38 | }, 39 | 40 | /** 41 | * Make the public JsMockito API available to Node.js / NodeUnit 42 | * @see JsMockito.Integration.importTo(global) 43 | */ 44 | Nodeunit: function() { 45 | JsMockito.Integration.importTo(global); 46 | }, 47 | 48 | /** 49 | * Make the public JsMockito API available to JsUnitTest 50 | * @see JsMockito.Integration.importTo(JsUnitTest.Unit.Testcase.prototype) 51 | */ 52 | JsUnitTest: function() { 53 | JsMockito.Integration.importTo(JsUnitTest.Unit.Testcase.prototype); 54 | }, 55 | 56 | /** 57 | * Make the public JsMockito API available to YUITest 58 | * @see JsMockito.Integration.importTo(window) 59 | */ 60 | YUITest: function() { 61 | JsMockito.Integration.importTo(window); 62 | }, 63 | 64 | /** 65 | * Make the public JsMockito API available to QUnit 66 | * @see JsMockito.Integration.importTo(window) 67 | */ 68 | QUnit: function() { 69 | JsMockito.Integration.importTo(window); 70 | }, 71 | 72 | /** 73 | * Make the public JsMockito API available to jsUnity 74 | * @see JsMockito.Integration.importTo(jsUnity.env.defaultScope) 75 | */ 76 | jsUnity: function() { 77 | JsMockito.Integration.importTo(jsUnity.env.defaultScope); 78 | }, 79 | 80 | /** 81 | * Make the public JsMockito API available to jSpec 82 | * @see JsMockito.Integration.importTo(jSpec.defaultContext) 83 | */ 84 | jSpec: function() { 85 | JsMockito.Integration.importTo(jSpec.defaultContext); 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /custom_rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/runner.js: -------------------------------------------------------------------------------- 1 | /* 2 | Sections of the code below taken from the blue-ridge rake plugin: 3 | 4 | http://github.com/relevance/blue-ridge 5 | 6 | Copyright (c) 2008-2009 Relevance, Inc. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | "Software"), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be 17 | included in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | load('../lib/env.rhino.js'); 29 | window.location = 'suite-dist.html'; 30 | 31 | var scripts = document.getElementsByTagName('script'); 32 | for (var i=0; i < scripts.length; i++) { 33 | if (scripts[i].getAttribute('type') == 'text/javascript') { 34 | try { 35 | load(scripts[i].src); 36 | } catch(e) { 37 | $error("Error loading script", e); 38 | } 39 | } 40 | } 41 | 42 | (function($) { 43 | var passed = 0; 44 | var failed = 0; 45 | 46 | $(Screw).bind("before", function(){ 47 | function example_name(element){ 48 | // TODO: handle nested describes! 49 | var context_name = $(element).parents(".describe").children("h1").text(); 50 | var example_name = $(element).children("h2").text(); 51 | 52 | return context_name + " - " + example_name; 53 | } 54 | 55 | $('.it').bind('passed', function() { 56 | passed++; 57 | java.lang.System.out.print("."); 58 | }).bind('failed', function(e, reason) { 59 | failed++; 60 | print("\nFAILED: " + example_name(this)); 61 | print(" " + reason + "\n"); 62 | }); 63 | }); 64 | 65 | $(Screw).bind("after", function() { 66 | var testCount = passed + failed; 67 | var elapsedTime = ((new Date() - Screw.suite_start_time)/1000.0); 68 | 69 | print("\n"); 70 | print(testCount + ' test(s), ' + failed + ' failure(s)'); 71 | print(elapsedTime.toString() + " seconds elapsed"); 72 | 73 | if (failed > 0) { java.lang.System.exit(1) }; 74 | java.lang.System.exit((failed > 0)? 1 : 0); 75 | }); 76 | })(jQuery); 77 | 78 | jQuery(window).trigger("load"); 79 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/screw-unit/screw.behaviors.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(Screw).bind('loaded', function() { 3 | $('.status').fn({ 4 | display: function() { 5 | $(this).html( 6 | $('.passed').length + $('.failed').length + ' test(s), ' + $('.failed').length + ' failure(s)
                  ' + 7 | ((new Date() - Screw.suite_start_time)/1000.0).toString() + " seconds elapsed" 8 | ); 9 | } 10 | }); 11 | 12 | $('.describe').fn({ 13 | parent: function() { 14 | return $(this).parent('.describes').parent('.describe'); 15 | }, 16 | 17 | run_befores: function() { 18 | $(this).fn('parent').fn('run_befores'); 19 | $(this).children('.befores').children('.before').fn('run'); 20 | }, 21 | 22 | run_afters: function() { 23 | $(this).fn('parent').fn('run_afters'); 24 | $(this).children('.afters').children('.after').fn('run'); 25 | }, 26 | 27 | enqueue: function() { 28 | $(this).children('.its').children('.it').fn('enqueue'); 29 | $(this).children('.describes').children('.describe').fn('enqueue'); 30 | }, 31 | 32 | selector: function() { 33 | return $(this).fn('parent').fn('selector') 34 | + ' > .describes > .describe:eq(' + $(this).parent('.describes').children('.describe').index(this) + ')'; 35 | } 36 | }); 37 | 38 | $('body > .describe').fn({ 39 | selector: function() { return 'body > .describe' } 40 | }); 41 | 42 | $('.it').fn({ 43 | parent: function() { 44 | return $(this).parent('.its').parent('.describe'); 45 | }, 46 | 47 | run: function() { 48 | try { 49 | try { 50 | $(this).fn('parent').fn('run_befores'); 51 | $(this).data('screwunit.run')(); 52 | } finally { 53 | $(this).fn('parent').fn('run_afters'); 54 | } 55 | $(this).trigger('passed'); 56 | } catch(e) { 57 | $(this).trigger('failed', [e]); 58 | } 59 | }, 60 | 61 | enqueue: function() { 62 | var self = $(this).trigger('enqueued'); 63 | $(Screw) 64 | .queue(function() { 65 | self.fn('run'); 66 | setTimeout(function() { $(Screw).dequeue() }, 0); 67 | }); 68 | }, 69 | 70 | selector: function() { 71 | return $(this).fn('parent').fn('selector') 72 | + ' > .its > .it:eq(' + $(this).parent('.its').children('.it').index(this) + ')'; 73 | } 74 | }); 75 | 76 | $('.before').fn({ 77 | run: function() { $(this).data('screwunit.run')() } 78 | }); 79 | 80 | $('.after').fn({ 81 | run: function() { $(this).data('screwunit.run')() } 82 | }); 83 | 84 | $(Screw).trigger('before'); 85 | var to_run = unescape(location.search.slice(1)) || 'body > .describe > .describes > .describe'; 86 | $(to_run) 87 | .focus() 88 | .eq(0).trigger('scroll').end() 89 | .fn('enqueue'); 90 | $(Screw).queue(function() { $(Screw).trigger('after') }); 91 | }) 92 | })(jQuery); 93 | -------------------------------------------------------------------------------- /src/com/karura/framework/utils/PackageInspector.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | 23 | package com.karura.framework.utils; 24 | 25 | import java.util.Enumeration; 26 | import java.util.HashMap; 27 | import java.util.List; 28 | 29 | import android.content.Context; 30 | import android.util.Log; 31 | 32 | import com.karura.framework.BuildConfig; 33 | import com.karura.framework.annotations.JavascriptModule; 34 | import com.karura.framework.plugins.WebViewPlugin; 35 | 36 | import dalvik.system.DexFile; 37 | 38 | public class PackageInspector { 39 | 40 | Context context; 41 | List pathsToInspect; 42 | 43 | public PackageInspector(Context context, List pathsToInspect) { 44 | this.context = context; 45 | this.pathsToInspect = pathsToInspect; 46 | } 47 | 48 | public HashMap> searchForPlugins(){ 49 | HashMap> result = new HashMap>(); 50 | try { 51 | DexFile df = new DexFile(context.getPackageCodePath()); 52 | for (Enumeration iter = df.entries(); iter.hasMoreElements();) { 53 | String entry = iter.nextElement(); 54 | for (String pluginPackagePath : pathsToInspect) { 55 | if (entry.startsWith(pluginPackagePath)) { 56 | Class clazz = null; 57 | try { 58 | 59 | clazz = (Class) Class.forName(entry); 60 | if (!WebViewPlugin.class.isAssignableFrom(clazz)) { 61 | continue; 62 | } 63 | if (clazz.getAnnotation(JavascriptModule.class) == null) { 64 | continue; 65 | } 66 | @SuppressWarnings("unchecked") 67 | Class webViewPlugin = (Class) clazz; 68 | result.put(clazz.getSimpleName(), webViewPlugin); 69 | } catch (Exception e) { 70 | if (BuildConfig.DEBUG){ 71 | e.printStackTrace(); 72 | } 73 | if (clazz != null){ 74 | Log.e(PackageInspector.class.getSimpleName(), clazz.getSimpleName() + " was ignored due to an error"); 75 | }else{ 76 | Log.e(PackageInspector.class.getSimpleName(), "Internal but recverable error"); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | }catch(Exception e){ 83 | Log.e(PackageInspector.class.getSimpleName(), "Error inspecting the application, could not find any plugins"); 84 | } 85 | return result; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/com/karura/framework/config/DalvikConfigLoader.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.config; 28 | 29 | import java.io.IOException; 30 | import java.util.regex.Matcher; 31 | import java.util.regex.Pattern; 32 | 33 | import org.xmlpull.v1.XmlPullParserException; 34 | 35 | import android.content.Context; 36 | import android.content.res.XmlResourceParser; 37 | import android.text.TextUtils; 38 | import android.util.Log; 39 | 40 | public class DalvikConfigLoader extends ConfigLoader { 41 | 42 | static final String TAG = "DalvikConfigLoader"; 43 | 44 | Context context; 45 | 46 | public DalvikConfigLoader(Context context) { 47 | this.context = context; 48 | } 49 | 50 | private static class DalvikXmlNode implements XMLNode { 51 | 52 | XmlResourceParser xml; 53 | 54 | DalvikXmlNode(XmlResourceParser xml) { 55 | this.xml = xml; 56 | } 57 | 58 | @Override 59 | public String getName() { 60 | return xml.getName(); 61 | } 62 | 63 | @Override 64 | public String getAttributeValue(String attr) { 65 | return xml.getAttributeValue(null, attr); 66 | } 67 | 68 | @Override 69 | public boolean getAttributeBooleanValue(String attr, boolean defaultVal) { 70 | return xml.getAttributeBooleanValue(null, attr, defaultVal); 71 | } 72 | } 73 | 74 | public ConfigStore loadConfig() { 75 | 76 | int id = context.getResources().getIdentifier("config", "xml", 77 | context.getPackageName()); 78 | 79 | if (id == 0) { 80 | Log.i(TAG, "config.xml missing. Ignoring..."); 81 | return configStore; 82 | } 83 | 84 | XmlResourceParser xml = context.getResources().getXml(id); 85 | int eventType = -1; 86 | 87 | while (eventType != XmlResourceParser.END_DOCUMENT) { 88 | if (eventType == XmlResourceParser.START_TAG) { 89 | elementStart(new DalvikXmlNode(xml)); 90 | } else if (eventType == XmlResourceParser.END_TAG) { 91 | elementEnd(new DalvikXmlNode(xml)); 92 | } 93 | try { 94 | eventType = xml.next(); 95 | } catch (XmlPullParserException e) { 96 | e.printStackTrace(); 97 | } catch (IOException e) { 98 | e.printStackTrace(); 99 | } 100 | } 101 | return configStore; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/com/karura/framework/utils/Reader.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | 23 | package com.karura.framework.utils; 24 | 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | import java.net.URL; 28 | import java.net.URLConnection; 29 | import java.util.Scanner; 30 | 31 | import android.content.res.Resources; 32 | 33 | public class Reader { 34 | public static String readRawString(Resources res, int resourceId) { 35 | StringBuilder sb = new StringBuilder(); 36 | Scanner s = new Scanner(res.openRawResource(resourceId)); 37 | 38 | while (s.hasNextLine()) { 39 | sb.append(s.nextLine() + "\n"); 40 | } 41 | 42 | return sb.toString(); 43 | } 44 | 45 | public static byte[] readRawByteArray(Resources res, int resourceId) { 46 | InputStream is = null; 47 | byte[] raw = new byte[] {}; 48 | try { 49 | is = res.openRawResource(resourceId); 50 | raw = new byte[is.available()]; 51 | is.read(raw); 52 | } catch (IOException e) { 53 | e.printStackTrace(); 54 | raw = null; 55 | } finally { 56 | try { 57 | is.close(); 58 | } catch (IOException e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | 63 | return raw; 64 | } 65 | 66 | public static String readRemoteString(String fileUrl) { 67 | StringBuilder sb = new StringBuilder(); 68 | 69 | try { 70 | URLConnection connection = (new URL(fileUrl)).openConnection(); 71 | connection.setConnectTimeout(10000); 72 | connection.setReadTimeout(10000); 73 | connection.connect(); 74 | 75 | Scanner s = new Scanner(connection.getInputStream()); 76 | 77 | while (s.hasNextLine()) { 78 | sb.append(s.nextLine() + "\n"); 79 | } 80 | } catch (Exception e) { 81 | e.printStackTrace(); 82 | } 83 | 84 | return sb.toString(); 85 | } 86 | 87 | public static byte[] readRemoteByteArray(String fileUrl) { 88 | InputStream is = null; 89 | byte[] raw = new byte[] {}; 90 | try { 91 | URLConnection connection = (new URL(fileUrl)).openConnection(); 92 | connection.setConnectTimeout(10000); 93 | connection.setReadTimeout(10000); 94 | connection.connect(); 95 | is = connection.getInputStream(); 96 | raw = new byte[is.available()]; 97 | is.read(raw); 98 | } catch (Exception e) { 99 | e.printStackTrace(); 100 | raw = null; 101 | } finally { 102 | try { 103 | if (is != null) { 104 | is.close(); 105 | } 106 | } catch (IOException e) { 107 | e.printStackTrace(); 108 | } 109 | } 110 | 111 | return raw; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/spec/object_spy_spec.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | Screw.Unit(function() { 3 | describe('JsMockito object spy', function() { 4 | var MyObject = function() { 5 | this.greeting = function() { return "hello" }; 6 | this.farewell = function() { return "goodbye" }; 7 | }; 8 | 9 | var mockObj; 10 | var proxyMock; 11 | before(function() { 12 | mockObj = mock(MyObject); 13 | mockObj.property = "foo"; 14 | proxyMock = spy(mockObj); 15 | }); 16 | 17 | describe("when created", function() { 18 | it("should copy properties", function() { 19 | assertThat(proxyMock.property, equalTo(mockObj.property)); 20 | }); 21 | }); 22 | 23 | describe("when method invoked", function() { 24 | before(function() { 25 | proxyMock.greeting(21); 26 | }); 27 | 28 | it("should invoke method on proxied object", function() { 29 | verify(mockObj).greeting(21); 30 | }); 31 | 32 | it("should invoke method on proxied object with delegate as scope", function() { 33 | verify(mockObj).greeting.call(mockObj, 21); 34 | }); 35 | }); 36 | 37 | describe("when method invoked with explicit scope", function() { 38 | var scope; 39 | before(function() { 40 | scope = {}; 41 | proxyMock.greeting.call(scope, 'foo'); 42 | }); 43 | 44 | it("should invoke method on proxied object with explicit scope", function() { 45 | verify(mockObj).greeting.apply(scope, [ 'foo' ]); 46 | }); 47 | }); 48 | 49 | describe("when method stubbed", function() { 50 | before(function() { 51 | when(proxyMock).greeting('hello').thenReturn('world'); 52 | }); 53 | 54 | describe("when method invoked with arguments matching stub", function() { 55 | var result; 56 | before(function() { 57 | result = proxyMock.greeting('hello'); 58 | }); 59 | 60 | it("should return result of stub", function() { 61 | assertThat(result, equalTo('world')); 62 | }); 63 | 64 | it("should not invoke the proxied object method", function() { 65 | verifyZeroInteractions(mockObj); 66 | }); 67 | }); 68 | 69 | describe("when method invoked with arguments not matching stub", function() { 70 | before(function() { 71 | proxyMock.greeting('foo'); 72 | }); 73 | 74 | it("should invoke the proxied function", function() { 75 | verify(mockObj).greeting('foo'); 76 | }); 77 | }); 78 | 79 | describe("when different method is invoked", function() { 80 | before(function() { 81 | proxyMock.farewell('hello'); 82 | }); 83 | 84 | it("should invoke the proxied function", function() { 85 | verify(mockObj).farewell('hello'); 86 | }); 87 | }); 88 | }); 89 | 90 | describe("when spying on a constructor", function() { 91 | MyObject.prototype = { 92 | foo: function() { return "bar" } 93 | }; 94 | 95 | var proxyConstructor; 96 | before(function() { 97 | ProxyObject = spy(MyObject); 98 | }); 99 | 100 | it("should construct objects correctly", function() { 101 | var obj = new ProxyObject(1); 102 | obj.foo(); 103 | verify(ProxyObject)(1); 104 | }); 105 | }); 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /src/com/karura/framework/config/JavaConfigLoader.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.config; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.io.IOException; 25 | 26 | import javax.xml.parsers.ParserConfigurationException; 27 | import javax.xml.parsers.SAXParser; 28 | import javax.xml.parsers.SAXParserFactory; 29 | 30 | import org.xml.sax.Attributes; 31 | import org.xml.sax.SAXException; 32 | import org.xml.sax.helpers.DefaultHandler; 33 | 34 | public class JavaConfigLoader extends ConfigLoader { 35 | 36 | String configFile; 37 | 38 | JavaConfigLoader(String configFile) { 39 | this.configFile = configFile; 40 | } 41 | 42 | public ConfigStore loadConfig() { 43 | SAXParserFactory factory = SAXParserFactory.newInstance(); 44 | try { 45 | SAXParser saxParser = factory.newSAXParser(); 46 | 47 | DefaultHandler handler = new DefaultHandler() { 48 | 49 | public void startElement(String uri, final String localName, 50 | String qName, final Attributes attributes) 51 | throws SAXException { 52 | elementStart(new XMLNode() { 53 | 54 | @Override 55 | public String getAttributeValue(String attr) { 56 | return attributes.getValue(null, attr); 57 | } 58 | 59 | @Override 60 | public String getName() { 61 | return localName; 62 | } 63 | 64 | @Override 65 | public boolean getAttributeBooleanValue(String attr, 66 | boolean defaultVal) { 67 | String result = getAttributeValue(attr); 68 | if (result == null) { 69 | return defaultVal; 70 | } 71 | return Boolean.valueOf(result); 72 | } 73 | 74 | }); 75 | 76 | } 77 | 78 | public void endElement(String uri, final String localName, 79 | String qName) throws SAXException { 80 | elementStart(new XMLNode() { 81 | 82 | @Override 83 | public String getAttributeValue(String attr) { 84 | return null; 85 | } 86 | 87 | @Override 88 | public String getName() { 89 | return localName; 90 | } 91 | 92 | @Override 93 | public boolean getAttributeBooleanValue(String attr, 94 | boolean defaultVal) { 95 | return false; 96 | } 97 | 98 | }); 99 | } 100 | }; 101 | 102 | saxParser.parse(configFile, handler); 103 | } catch (ParserConfigurationException e) { 104 | e.printStackTrace(); 105 | } catch (SAXException e) { 106 | e.printStackTrace(); 107 | } catch (IOException e) { 108 | // TODO Auto-generated catch block 109 | e.printStackTrace(); 110 | } 111 | return configStore; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/jquery/jquery.print.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | function print_array(obj, opts) { 4 | var result = []; 5 | for (var i = 0; i < Math.min(opts.max_array, obj.length); i++) 6 | result.push($.print(obj[i], $.extend({}, opts, { max_array: 3, max_string: 40 }))); 7 | 8 | if (obj.length > opts.max_array) 9 | result.push((obj.length - opts.max_array) + ' more...'); 10 | if (result.length == 0) return "[]" 11 | return "[ " + result.join(", ") + " ]"; 12 | } 13 | 14 | function print_element(obj) { 15 | if (obj.nodeType == 1) { 16 | var result = []; 17 | var properties = [ 'className', 'id' ]; 18 | var extra = { 19 | 'input': ['type', 'name', 'value'], 20 | 'a': ['href', 'target'], 21 | 'form': ['method', 'action'], 22 | 'script': ['src'], 23 | 'link': ['href'], 24 | 'img': ['src'] 25 | }; 26 | 27 | $.each(properties.concat(extra[obj.tagName.toLowerCase()] || []), function(){ 28 | if (obj[this]) 29 | result.push(' ' + this.replace('className', 'class') + "=" + $.print(obj[this])) 30 | }); 31 | return "<" + obj.tagName.toLowerCase() 32 | + result.join('') + ">"; 33 | } 34 | } 35 | 36 | function print_object(obj, opts) { 37 | var seen = opts.seen || [ obj ]; 38 | 39 | var result = [], key, value; 40 | for (var k in obj) { 41 | if (obj.hasOwnProperty(k) && $.inArray(obj[k], seen) < 0) { 42 | seen.push(obj[k]); 43 | value = $.print(obj[k], $.extend({}, opts, { max_array: 6, max_string: 40, seen: seen })); 44 | } else 45 | value = "..."; 46 | result.push(k + ": " + value); 47 | } 48 | if (result.length == 0) return "{}"; 49 | return "{ " + result.join(", ") + " }"; 50 | } 51 | 52 | function print_string(value, opts) { 53 | var character_substitutions = { 54 | '\b': '\\b', 55 | '\t': '\\t', 56 | '\n': '\\n', 57 | '\f': '\\f', 58 | '\r': '\\r', 59 | '"' : '\\"', 60 | '\\': '\\\\' 61 | }; 62 | var r = /["\\\x00-\x1f\x7f-\x9f]/g; 63 | 64 | var str = r.test(value) 65 | ? '"' + value.replace(r, function (a) { 66 | var c = character_substitutions[a]; 67 | if (c) return c; 68 | c = a.charCodeAt(); 69 | return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); 70 | }) + '"' 71 | : '"' + value + '"'; 72 | if (str.length > opts.max_string) 73 | return str.slice(0, opts.max_string + 1) + '..."'; 74 | else 75 | return str; 76 | } 77 | 78 | $.print = function(obj, options) { 79 | var opts = $.extend({}, { max_array: 10, max_string: 100 }, options); 80 | 81 | if (typeof obj == 'undefined') 82 | return "undefined"; 83 | else if (typeof obj == 'boolean') 84 | return obj.toString(); 85 | else if (!obj && typeof obj == 'number') 86 | return 'NaN'; 87 | else if (!obj) 88 | return "null"; 89 | else if (typeof obj == 'string') 90 | return print_string(obj, opts); 91 | else if (obj instanceof RegExp) 92 | return obj.toString(); 93 | else if (obj instanceof Array || obj.callee || obj.item) 94 | return print_array(obj, opts); 95 | else if (typeof obj == 'function' || obj instanceof Function) 96 | return obj.toString().match(/^([^)]*\))/)[1]; 97 | else if (obj.nodeType) 98 | return print_element(obj); 99 | else if (obj instanceof jQuery) 100 | return "$(" + $.print(obj.get()) + ")"; 101 | else if (obj instanceof Error) 102 | return print_object(obj, $.extend({}, options, { max_string: 200 })); 103 | else if (obj instanceof Object) 104 | return print_object(obj, opts); 105 | else 106 | return obj.toString().replace(/\n\s*/g, ''); 107 | } 108 | 109 | })(jQuery); -------------------------------------------------------------------------------- /prebuilt/jsmockito/src/function.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | 3 | /** 4 | * Create a mockable and stubbable anonymous function. 5 | * 6 | *

                  Once created, the function can be invoked and will return undefined for 7 | * any interactions that do not match stub declarations.

                  8 | * 9 | *
                   10 |  * var mockFunc = JsMockito.mockFunction();
                   11 |  * JsMockito.when(mockFunc).call(anything(), 1, 5).thenReturn(6);
                   12 |  * mockFunc(1, 5); // result is 6
                   13 |  * JsMockito.verify(mockFunc)(1, greaterThan(2));
                   14 |  * 
                  15 | * 16 | * @param funcName {string} The name of the mock function to use in messages 17 | * (defaults to 'func') 18 | * @param delegate {function} The function to delegate unstubbed calls to 19 | * (optional) 20 | * @return {function} an anonymous function 21 | */ 22 | JsMockito.mockFunction = function(funcName, delegate) { 23 | if (typeof funcName == 'function') { 24 | delegate = funcName; 25 | funcName = undefined; 26 | } 27 | funcName = funcName || 'func'; 28 | delegate = delegate || function() { }; 29 | 30 | var stubMatchers = [] 31 | var interactions = []; 32 | 33 | var mockFunc = function() { 34 | var args = [this]; 35 | args.push.apply(args, arguments); 36 | interactions.push({args: args}); 37 | 38 | var stubMatcher = JsMockito.find(stubMatchers, function(stubMatcher) { 39 | return JsMockito.matchArray(stubMatcher[0], args); 40 | }); 41 | if (stubMatcher == undefined) 42 | return delegate.apply(this, arguments); 43 | var stubs = stubMatcher[1]; 44 | if (stubs.length == 0) 45 | return undefined; 46 | var stub = stubs[0]; 47 | if (stubs.length > 1) 48 | stubs.shift(); 49 | return stub.apply(this, arguments); 50 | }; 51 | 52 | mockFunc.prototype = delegate.prototype; 53 | 54 | JsMockito.defineProperty(mockFunc, '_jsMockitoStubBuilder', { 55 | enumerable: false, 56 | value: function(contextMatcher) { 57 | var contextMatcher = contextMatcher || JsHamcrest.Matchers.anything(); 58 | return matcherCaptureFunction(contextMatcher, function(matchers) { 59 | var stubMatch = [matchers, []]; 60 | stubMatchers.unshift(stubMatch); 61 | return { 62 | then: function() { 63 | stubMatch[1].push.apply(stubMatch[1], arguments); 64 | return this; 65 | }, 66 | thenReturn: function() { 67 | return this.then.apply(this,JsMockito.map(arguments, function(value) { 68 | return function() { return value }; 69 | })); 70 | }, 71 | thenThrow: function(exception) { 72 | return this.then.apply(this,JsMockito.map(arguments, function(value) { 73 | return function() { throw value }; 74 | })); 75 | } 76 | }; 77 | }); 78 | } 79 | }); 80 | 81 | JsMockito.defineProperty(mockFunc, '_jsMockitoVerifier', { 82 | enumerable: false, 83 | value: function(verifier, contextMatcher) { 84 | var contextMatcher = contextMatcher || JsHamcrest.Matchers.anything(); 85 | return matcherCaptureFunction(contextMatcher, function(matchers) { 86 | return verifier(funcName, interactions, matchers, matchers[0] != contextMatcher); 87 | }); 88 | } 89 | }); 90 | 91 | JsMockito.defineProperty(mockFunc, '_jsMockitoMockFunctions', { 92 | enumerable: false, 93 | value: function() { 94 | return [ mockFunc ]; 95 | } 96 | }); 97 | 98 | return mockFunc; 99 | 100 | function matcherCaptureFunction(contextMatcher, handler) { 101 | return JsMockito.contextCaptureFunction(contextMatcher, 102 | function(context, args) { 103 | var matchers = JsMockito.mapToMatchers([context].concat(args || [])); 104 | return handler(matchers); 105 | } 106 | ); 107 | }; 108 | }; 109 | JsMockito._export.push('mockFunction'); 110 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/Logger.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attribution. 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.plugins; 28 | 29 | import android.os.Bundle; 30 | import android.util.Log; 31 | 32 | import com.karura.framework.ui.webview.KaruraWebView; 33 | //#if TARGET_SDK==17 34 | import android.webkit.JavascriptInterface; 35 | //#endif 36 | 37 | import com.karura.framework.PluginManager; 38 | import com.karura.framework.annotations.JavascriptModule; 39 | import com.karura.framework.annotations.Param; 40 | import com.karura.framework.annotations.Params; 41 | import com.karura.framework.annotations.SupportJavascriptInterface; 42 | import com.karura.framework.annotations.Synchronous; 43 | import com.karura.framework.annotations.Description; 44 | 45 | @JavascriptModule 46 | @Description("Use android logging facility") 47 | public class Logger extends WebViewPlugin { 48 | 49 | public Logger(int pluginId, PluginManager pluginManager, KaruraWebView webView, Bundle savedInstance) { 50 | super(pluginId, pluginManager, webView, savedInstance); 51 | } 52 | 53 | //#if TARGET_SDK==17 54 | @JavascriptInterface 55 | //#endif 56 | @SupportJavascriptInterface 57 | @Synchronous(retVal="none") 58 | @Description("Log an error log in the android syslogger") 59 | @Params({ 60 | @Param(name="Tag", description ="Tag to be used for logging in the android log system"), 61 | @Param(name="msg", description="The message to be logged.") 62 | }) 63 | public void e(String Tag, String msg) { 64 | Log.e(Tag, msg); 65 | } 66 | 67 | //#if TARGET_SDK==17 68 | @JavascriptInterface 69 | //#endif 70 | @SupportJavascriptInterface 71 | @Synchronous(retVal="none") 72 | @Description("Log a debug log in the android syslogger") 73 | @Params({ 74 | @Param(name="Tag", description ="Tag to be used for logging in the android log system"), 75 | @Param(name="msg", description="The message to be logged.") 76 | }) 77 | public void d(String Tag, String msg) { 78 | Log.d(Tag, msg); 79 | } 80 | 81 | //#if TARGET_SDK==17 82 | @JavascriptInterface 83 | //#endif 84 | @SupportJavascriptInterface 85 | @Synchronous(retVal="none") 86 | @Description("Log a verbose log in the android syslogger") 87 | @Params({ 88 | @Param(name="Tag", description ="Tag to be used for logging in the android log system"), 89 | @Param(name="msg", description="The message to be logged.") 90 | }) 91 | public void v(String Tag, String msg) { 92 | Log.v(Tag, msg); 93 | } 94 | 95 | //#if TARGET_SDK==17 96 | @JavascriptInterface 97 | //#endif 98 | @SupportJavascriptInterface 99 | @Synchronous(retVal="none") 100 | @Description("Log an info log in the android syslogger") 101 | @Params({ 102 | @Param(name="Tag", description ="Tag to be used for logging in the android log system"), 103 | @Param(name="msg", description="The message to be logged.") 104 | }) 105 | public void i(String Tag, String msg) { 106 | Log.i(Tag, msg); 107 | } 108 | 109 | @Override 110 | public void onSaveInstanceState(Bundle saveInInstance) { 111 | // TODO Auto-generated method stub 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/README.md: -------------------------------------------------------------------------------- 1 | JsMockito 2 | --------- 3 | 4 | http://github.com/chrisleishman/jsmockito/tree/master 5 | 6 | JsMockito is a JavaScript stub/mock framework heavily inspired by 7 | Mockito. To quote the mockito website: 8 | 9 | "Mockito is a mocking framework that tastes really good. It 10 | lets you write beautiful tests with a clean & simple API. 11 | Mockito doesn't give you a hangover because the tests are 12 | very readable and they produce clean verification errors." 13 | 14 | JsMockito aims to try and reproduce the clean & simple API, with a 15 | JavaScript twist. And why not add some variation to your drinking habits? 16 | 17 | 18 | What do you serve it with? 19 | -------------------------- 20 | 21 | JsMockito must be served with JsHamcrest. Not only do they go well 22 | together, it's essential to avoid a very nasty hangover. Get 23 | JsHamcrest from here: 24 | 25 | http://github.com/danielfm/jshamcrest/ 26 | 27 | 28 | How to drink it? 29 | ---------------- 30 | 31 | To use JsMockito with a JavaScript unit test framework, follow the usual 32 | installation/configuration instructions for the framework and plug JsMockito 33 | into it. If you're integrating with Screw.Unit (and why wouldn't you?) then you 34 | just need to make the following calls: 35 | 36 | JsHamcrest.Integration.screwunit(); 37 | JsMockito.Integration.screwunit(); 38 | 39 | Once installed, you can verify with interactions: 40 | 41 | var mockedObject = mock(Array); 42 | 43 | // -- start code under test -- 44 | mockedObject.push("one"); 45 | // -- end code under test -- 46 | 47 | verify(mockedObject).push("one"); 48 | 49 | Or you can stub method calls: 50 | 51 | var mockedObject = mock(Array); 52 | 53 | when(mockedObject).get(1).thenReturn("hello world"); 54 | 55 | // -- start code under test -- 56 | alert(mockedObject.get(1)); 57 | 58 | // the following alerts 'true' as get(99) was not stubbed 59 | alert(typeof (mockedObject.get(99)) === 'undefined'); 60 | // -- end code under test -- 61 | 62 | For a JavaScript twist, you can also mock functions: 63 | 64 | mockFunc = mockFunction(); 65 | when(mockFunc)(anything()).then(function(arg) { 66 | return "foo " + arg; 67 | }); 68 | 69 | // -- start code under test -- 70 | mockFunc("bar"); 71 | // -- end code under test -- 72 | 73 | verify(mockFunc)(anything()); 74 | 75 | // or if you want to verify the scope it was called with, use: 76 | verify(mockFunc).call(this, anything()) 77 | 78 | Mockitos are also good for spys 79 | ------------------------------- 80 | 81 | Real super spies don't drink martinis - they go for mockitos. And just like 82 | Mockito, JsMockito supports 'spying' (e.g. partial mocking) on real functions 83 | and objects and verifing how they were interacted with. 84 | 85 | An example with functions: 86 | 87 | realFunc = function(msg) { alert(msg) }; 88 | mockFunc = spy(realFunc); 89 | 90 | // -- start code under test -- 91 | // the following alerts 'hello world' 92 | mockFunc("hello world"); 93 | // -- end code under test -- 94 | 95 | verify(mockFunc)("hello world"); 96 | 97 | or with objects: 98 | 99 | realObj = new Array(); 100 | mockedObj = spy(realObj); 101 | 102 | when(mockedObj).pop().thenReturn("bar"); 103 | 104 | // -- start code under test -- 105 | mockedObject.push("foo"); 106 | alert(realObj.length); // alerts '1' 107 | 108 | alert(mockedObject.pop()); // alerts 'bar' 109 | alert(realObj.length); // still alerts '1' 110 | // -- end code under test -- 111 | 112 | verify(mockedObject).push("foo"); 113 | verify(mockedObject).pop(); 114 | 115 | For more examples and documentation, run 'ant doc' and then look in the doc directory. 116 | 117 | 118 | Who is your bartender? 119 | ---------------------- 120 | 121 | This variation is served to you by Chris Leishman and friends. Also a big 122 | thank you to the mockito guys for the inspiration! 123 | 124 | Also thanks to the JsHamcrest authors, who made this easy. 125 | -------------------------------------------------------------------------------- /src/com/karura/framework/utils/JsHelper.java: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | ============== GPL License ============== 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | 19 | ============== Commercial License============== 20 | https://github.com/karuradev/licenses/blob/master/toc.txt 21 | */ 22 | 23 | package com.karura.framework.utils; 24 | 25 | import org.json.JSONException; 26 | import org.json.JSONObject; 27 | 28 | import android.util.Pair; 29 | 30 | import com.karura.framework.plugins.PluginConstants; 31 | 32 | public class JsHelper implements PluginConstants { 33 | public static final String BACK_PRESSED = "javascript: karura.events.onBackPressed();"; 34 | public static final String OPTIONS_MENU_KEY_DOWN = "javascript: karura.events.onOptionsMenuKeyDown();"; 35 | 36 | public static final String KARURA_DISPATCH = "javascript: %s.dispatcher.dispatch('%s');"; 37 | 38 | private static final String SEPARATOR_COMMA = ", "; 39 | private static final String ARRAY_LITERAL_RIGHT = "]"; 40 | private static final String ARRAY_LITERAL_LEFT = "["; 41 | private static final String STRING_LITERAL_ESCAPE = "\\\""; 42 | private static final String STRING_LITERAL_BACKSLASH = "\""; 43 | 44 | public static String literal(Object value) { 45 | return (value instanceof Number) ? value.toString() : stringLiteral(value); 46 | } 47 | 48 | private static String[] literals(Object... values) { 49 | String[] literals = new String[values.length]; 50 | for (int i = 0; i < values.length; ++i) { 51 | literals[i] = literal(values[i]); 52 | } 53 | return literals; 54 | } 55 | 56 | private static String stringLiteral(Object value) { 57 | return STRING_LITERAL_BACKSLASH + value.toString().replaceAll(STRING_LITERAL_BACKSLASH, STRING_LITERAL_ESCAPE) + STRING_LITERAL_BACKSLASH; 58 | } 59 | 60 | private static String join(String separator, String... strings) { 61 | StringBuilder buffer = new StringBuilder(); 62 | String s = ""; 63 | for (String string : strings) { 64 | buffer.append(s); 65 | s = separator; 66 | buffer.append(string); 67 | } 68 | return buffer.toString(); 69 | } 70 | 71 | public static String jsFragmentForAsyncResponse(String receiver, String method, String action, int timeout, Pair... params) throws IllegalArgumentException { 72 | JSONObject payload = new JSONObject(); 73 | try { 74 | payload.put("receiver", receiver); 75 | String method2 = Character.toUpperCase(method.charAt(0)) + method.substring(1); 76 | payload.put("method", method2); 77 | if (timeout != INVALID_TIMEOUT) { 78 | payload.put("timeout", timeout); 79 | } 80 | if (action != null) { 81 | payload.put("action", action); 82 | } 83 | JSONObject apiPayload = new JSONObject(); 84 | for (Pair p : params) { 85 | apiPayload.put((String) p.first, p.second); 86 | } 87 | payload.put("data", apiPayload); 88 | } catch (JSONException e) { 89 | throw new IllegalArgumentException(); 90 | } 91 | String stringify = payload.toString(); 92 | 93 | return stringify; 94 | } 95 | 96 | public static String notify(String dispatchHandle, int id) { 97 | return String.format(KARURA_DISPATCH, dispatchHandle, id); 98 | } 99 | 100 | public static String arrayLiterals(Object... values) { 101 | return ARRAY_LITERAL_LEFT + JsHelper.join(SEPARATOR_COMMA, literals(values)) + ARRAY_LITERAL_RIGHT; 102 | } 103 | 104 | public static String escapeJs(String javascript) { 105 | return javascript.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\\"", "\\\\\""); 106 | } 107 | } -------------------------------------------------------------------------------- /assets/karura/js/framework/scripts.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | /** 23 | * Script.js 24 | * This javascript module allows you to dynamically load and append javascripts to DOM 25 | * Upon successful loading of the javascript the caller is notified of the result successful 26 | * or otherwise 27 | */ 28 | ;(function(window, document, undefined) { 29 | 'use strict'; 30 | 31 | var exports = window.exports; 32 | var debug = window.debug; 33 | 34 | /** 35 | * The constructor for the module 36 | */ 37 | function Scripts() { 38 | if (!(this instanceof Scripts)) { 39 | return new Scripts(); 40 | } 41 | return this; 42 | } 43 | 44 | /* 45 | * Private methods 46 | */ 47 | 48 | /** 49 | * This method when called will remove a script node from dom. 50 | * @param id Specifies Id of the script which needs to be removed. 51 | */ 52 | function removeScript(id) { 53 | var scripts = document.getElementsByTagName('script'); 54 | 55 | for (var i = 0; i < scripts.length; i++) { 56 | var script = scripts[i]; 57 | if (script.id == id) { 58 | debug.info('[Scripts] Removing script with id: ' + id); 59 | script.parentNode.removeChild(script); 60 | script = null; 61 | } 62 | } 63 | } 64 | 65 | /* 66 | * Public APIs 67 | */ 68 | Scripts.prototype = { 69 | constructor : Scripts, 70 | 71 | VERSION : '1.0', 72 | 73 | /** 74 | * Use this api to load and append a javascript to DOM 75 | * src : url of the script to be appended to DOM 76 | * where : name of the element to which the specified script has to be appended 77 | * id : unique identifier for the script 78 | * callback : An optional callback method to be called once the script has been 79 | * successfully loaded into memory. Prototype of the function called 80 | * upon completion : callback(boolean success) 81 | */ 82 | load : function(src, where, id, callback) { 83 | debug.log('[Scripts] load called to request script src: ' + src + ' id: ' + id); 84 | 85 | //remove past instance of the script if any 86 | removeScript(id); 87 | 88 | var script = document.createElement('script'); 89 | 90 | script.src = src; 91 | script.type = 'text/javascript'; 92 | script.async = true; //load the script asynchronously 93 | script.charset = 'UTF-8'; 94 | script.setAttribute('id', id); 95 | 96 | //setting up the event handler for when the script is loaded successfully or otherwise 97 | script.onreadystatechange = script.onload = function() { 98 | var state = document.readyState; 99 | if (_.isFunction(callback) && (!state || /loaded|complete/i.test(state))) { 100 | debug.info('[Scripts] delivering script ready callback for src: ' + src); 101 | callback(true); 102 | } 103 | }; 104 | 105 | //append the script at its correct location 106 | document.querySelector(where || 'head').appendChild(script); 107 | debug.info('[Scripts] completed script loading'); 108 | }, 109 | 110 | toString : function() { 111 | return '[Scripts]'; 112 | } 113 | }; 114 | 115 | /* 116 | * Make this class final 117 | */ 118 | (Object.freeze||Object)(Scripts.prototype); 119 | 120 | /* 121 | * Make this class accessible in the exports namespace 122 | */ 123 | exports.add('Scripts', Scripts); 124 | }(window, document)); 125 | -------------------------------------------------------------------------------- /src/com/karura/framework/config/ConfigLoader.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.config; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.util.regex.Matcher; 25 | import java.util.regex.Pattern; 26 | 27 | import android.text.TextUtils; 28 | import android.util.Log; 29 | 30 | public abstract class ConfigLoader { 31 | 32 | static final String TAG = "ConfigLoader"; 33 | 34 | public abstract ConfigStore loadConfig() ; 35 | 36 | protected ConfigStore configStore = new ConfigStore(); 37 | private boolean frameworkBlock = false, whitelistBlock = false; 38 | 39 | 40 | 41 | protected void elementStart(XMLNode xml){ 42 | String strNode = xml.getName(); 43 | if (strNode.equals("framework")) { 44 | frameworkBlock = true; 45 | } else if (frameworkBlock && strNode.equals("name")) { 46 | configStore.setFrameworkName(xml.getAttributeValue("value")); 47 | } else if (frameworkBlock && strNode.equals("version")) { 48 | configStore.setFrameworkVersion(xml.getAttributeValue("value")); 49 | } else if (frameworkBlock && strNode.equals("no_activity_title")) { 50 | configStore.showActivityTitle(xml.getAttributeValue("value")); 51 | } else if (frameworkBlock && strNode.equals("full_screen")) { 52 | configStore.showActivityFullScreen(xml.getAttributeValue("value")); 53 | } else if (frameworkBlock && strNode.equals("access")) { 54 | String origin = xml.getAttributeValue("origin"); 55 | String subdomains = xml.getAttributeValue("subdomains"); 56 | if (origin != null) { 57 | configStore.addWhitelistEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); 58 | } 59 | } else if (frameworkBlock && strNode.equals("log")) { 60 | String level = xml.getAttributeValue("level"); 61 | Log.i(TAG, String.format("Found Log level %s", level)); 62 | if (level != null) { 63 | configStore.setLogLevel(level); 64 | } 65 | } else if (frameworkBlock && strNode.equals("plugin-path")){ 66 | String pkg = xml.getAttributeValue("package"); 67 | if (!TextUtils.isEmpty(pkg)){ 68 | configStore.addPackagePath(pkg); 69 | } 70 | } 71 | else if (frameworkBlock && strNode.equals("homeurl")) { 72 | String src = xml.getAttributeValue("src"); 73 | 74 | Log.i(TAG, String.format("Found start page location: %s", src)); 75 | 76 | if (src != null) { 77 | Pattern schemeRegex = Pattern.compile("^[a-z]+://"); 78 | Matcher matcher = schemeRegex.matcher(src); 79 | if (matcher.find()) { 80 | configStore.setStartUrl(src); 81 | } else { 82 | if (src.charAt(0) == '/') { 83 | src = src.substring(1); 84 | } 85 | configStore.setStartUrl("file:///android_asset/" + src); 86 | } 87 | } 88 | } else if (frameworkBlock && strNode.equals("whitelist")) { 89 | whitelistBlock = true; 90 | } else if (frameworkBlock && whitelistBlock && strNode.equals("item")) { 91 | String src = xml.getAttributeValue("src"); 92 | Boolean subdomains = xml.getAttributeBooleanValue("subdomains", false); 93 | if (src != null) { 94 | configStore.addWhitelistEntry(src, subdomains); 95 | } 96 | } 97 | } 98 | 99 | protected void elementEnd(XMLNode xml){ 100 | String strNode = xml.getName(); 101 | if (strNode.equals("framework")) { 102 | frameworkBlock = false; 103 | } else if (frameworkBlock && strNode.equals("whitelist")) { 104 | whitelistBlock = false; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/com/karura/framework/ui/webview/KaruraWebChromeClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | /** 23 | This file derived from Cordova Android Project available under the Apache 2.0 License 24 | Please refer to APACHE-LICENCE2.0.txt for attributions 25 | */ 26 | 27 | package com.karura.framework.ui.webview; 28 | 29 | import android.app.AlertDialog; 30 | import android.content.DialogInterface; 31 | import android.util.Log; 32 | import android.webkit.ConsoleMessage; 33 | import android.webkit.ConsoleMessage.MessageLevel; 34 | import android.webkit.JsPromptResult; 35 | import android.webkit.JsResult; 36 | import android.webkit.WebChromeClient; 37 | import android.webkit.WebStorage; 38 | import android.webkit.WebView; 39 | 40 | import com.karura.framework.R; 41 | 42 | public class KaruraWebChromeClient extends WebChromeClient { 43 | 44 | public KaruraWebChromeClient(KaruraWebView webViewEx) { 45 | } 46 | 47 | @Override 48 | public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { 49 | new AlertDialog.Builder(view.getContext()).setTitle(R.string.title_dialog_alert).setMessage(message) 50 | .setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() { 51 | @Override 52 | public void onClick(DialogInterface dialog, int which) { 53 | result.confirm(); 54 | } 55 | }).setCancelable(false).create().show(); 56 | 57 | return true; 58 | } 59 | 60 | @Override 61 | public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { 62 | new AlertDialog.Builder(view.getContext()).setTitle(R.string.title_dialog_confirm).setMessage(message) 63 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 64 | public void onClick(DialogInterface dialog, int which) { 65 | result.confirm(); 66 | } 67 | }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 68 | public void onClick(DialogInterface dialog, int which) { 69 | result.cancel(); 70 | } 71 | }).create().show(); 72 | 73 | return true; 74 | } 75 | 76 | @Override 77 | public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { 78 | return true; 79 | } 80 | 81 | @Override 82 | public void onProgressChanged(WebView view, int progress) { 83 | super.onProgressChanged(view, progress); 84 | // activity.setProgress(progress * 1000); 85 | } 86 | 87 | @Override 88 | public void onReceivedTitle(WebView view, String title) { 89 | KaruraWebView karuraWebView = (KaruraWebView) view; 90 | 91 | super.onReceivedTitle(view, title); 92 | } 93 | 94 | @Override 95 | public boolean onConsoleMessage(ConsoleMessage cm) { 96 | if (cm.message() == null){ 97 | Log.e(KaruraWebView.TAG, "You passed null as the log message. This request has been ignored."); 98 | return false; 99 | } 100 | if (cm.messageLevel() == MessageLevel.ERROR) { 101 | Log.e(KaruraWebView.TAG, cm.message() + " at line " + cm.lineNumber() + " in file " + cm.sourceId()); 102 | } else { 103 | Log.i(KaruraWebView.TAG, cm.message()); 104 | } 105 | return true; 106 | } 107 | 108 | @Override 109 | public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota, 110 | WebStorage.QuotaUpdater quotaUpdater) { 111 | quotaUpdater.updateQuota(estimatedSize * 2); // double it 112 | } 113 | } -------------------------------------------------------------------------------- /assets/karura/js/framework/dispatcher.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | ;(function(window, document, undefined){ 23 | 'use strict'; 24 | 25 | function Dispatcher(karura){ 26 | if (!(this instanceof Dispatcher)){ 27 | return new Dispatcher(karura); 28 | } 29 | 30 | Object.defineProperties(this, { 31 | 'karura' : { 32 | get : function() { 33 | return karura; 34 | } 35 | }, 36 | 'objectMap' : { 37 | get : function() { 38 | return karura.objectMap; 39 | } 40 | }, 41 | 'callMap' : { 42 | get : function() { 43 | return karura.callMap; 44 | } 45 | } 46 | }); 47 | 48 | return this; 49 | } 50 | 51 | Dispatcher.prototype = { 52 | constructor : Dispatcher, 53 | 54 | VERSION : '1.0', 55 | 56 | dispatch : function(id){ 57 | /* 58 | * This method is called from the java layer to trigger an event or a callback in the 59 | * javascript layer. 60 | * 61 | * @param id: it is the id of the script which contains the js fragment corresponding to 62 | * this request. When this event is trigger the javascript layer will request the java layer 63 | * for the js fragment which is then appended to dom and executed. 64 | */ 65 | 66 | id = parseInt(id, 10); 67 | if (_.isNumber(id)) { 68 | var self = this; 69 | 70 | var objectDispatch = function(_json) { 71 | var json = JSON.parse(_json); 72 | var data = json.data.data; 73 | 74 | var action = ('action' in json) && json.action; 75 | 76 | var receiver = json.receiver; 77 | var callId = json.method; 78 | var timeout = ('timeout' in json) && json.timeout; // not in use! 79 | 80 | var objectReceiver = self.objectMap.getById(receiver); 81 | var objectReceiverMethod; 82 | 83 | var receiverOptions = self.callMap.getById(callId); 84 | 85 | //Todo fix for events 86 | if (_.isObject(objectReceiver) && _.isObject(receiverOptions)) { 87 | if (action !== undefined) { 88 | objectReceiverMethod = receiverOptions[action]; 89 | } else { 90 | objectReceiverMethod = 'On' + method + 'Listener'; 91 | } 92 | var func = objectReceiverMethod || null; 93 | if (_.isFunction(func)) { 94 | func.apply(objectReceiver, [data, globals]); 95 | } else { 96 | debug.error('[karura] Not a function: ' + func); 97 | } 98 | 99 | if (action !== null && (action == "resolve" || action == "reject")){ 100 | self.callMap.remove(callId, receiverOptions); 101 | } 102 | } else { 103 | //Nothing much can be done in this case except for ignoring the request 104 | debug.error('[karura] Object receiver does not exist: ' + receiver + ' -- ' + JSON.stringify(json)); 105 | } 106 | }; 107 | 108 | //asynchronously try and load the javascript fragment 109 | setTimeout(function() { 110 | try { 111 | var _json = self.karura.getJsWithId(id); 112 | objectDispatch(_json); 113 | } catch (e) { 114 | debug.error('[karura] Error stack: ' + e.stack); 115 | } 116 | }, 0); 117 | } else { 118 | debug.error('[karura] Supplied javascript fragment id is not an integer: ' + id); 119 | } 120 | } 121 | }; 122 | 123 | /* 124 | * Make this class final 125 | */ 126 | (Object.freeze||Object)(Dispatcher.prototype); 127 | 128 | /* 129 | * Make this class accessible in the exports namespace 130 | */ 131 | window.exports.add('Dispatcher', Dispatcher); 132 | }(window, document)); 133 | -------------------------------------------------------------------------------- /autogen/com/karura/autogen/codegen/FrameworkGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | package com.karura.autogen.codegen; 23 | 24 | import java.util.HashMap; 25 | 26 | import com.karura.autogen.utils.SourceBuffer; 27 | import com.karura.framework.FrameworkConfig; 28 | import com.karura.framework.PluginManager; 29 | import com.karura.framework.plugins.WebViewPlugin; 30 | 31 | public class FrameworkGenerator extends PluginGenerator { 32 | 33 | HashMap> pluginMap; 34 | 35 | public FrameworkGenerator(HashMap> pluginMap) { 36 | super(PluginManager.class); 37 | this.pluginMap = pluginMap; 38 | } 39 | 40 | @Override 41 | public void applyToBuffer(SourceBuffer gen) { 42 | 43 | startAnonymousSelfExecutingFunction(gen, true); 44 | defineVariable(gen, "exports = window.exports", "globals = window.globals", "debug = window.debug"); 45 | 46 | SourceBuffer pluginGen = new SourceBuffer(); 47 | for (Class clazz : pluginMap.values()) { 48 | 49 | new PluginGenerator(clazz).applyToBuffer(pluginGen); 50 | gen.addLine(pluginGen.toString()); 51 | pluginGen.reset(); 52 | } 53 | 54 | // --- start --- 55 | // definition of the FrameworkFacade Wrapper javascript function 56 | 57 | startFunction(gen, false, FrameworkConfig.FRAMEWORK_JS_CLASS_NAME, "objectMap", "callMap"); 58 | 59 | gen.sB("if (!(this instanceof " + FrameworkConfig.FRAMEWORK_JS_CLASS_NAME + ")) "); 60 | gen.addLine("return new " + FrameworkConfig.FRAMEWORK_JS_CLASS_NAME + "(objectMap, callMap);"); 61 | gen.eB(); 62 | 63 | gen.sB("if (objectMap == null)"); 64 | gen.addLine("objectMap = new window.exports.ObjectMap();"); 65 | gen.eB(); 66 | 67 | gen.sB("if (callMap == null)"); 68 | gen.addLine("callMap = new window.exports.ObjectMap();"); 69 | gen.eB(); 70 | 71 | defineVariable(gen, "dispatcher = new window.exports.Dispatcher(this)"); 72 | 73 | defineVariable(gen, "nextCallId = 1"); 74 | 75 | defineProperty(gen, "objectMap", "return objectMap;", null); 76 | defineProperty(gen, "callMap", "return callMap;", null); 77 | defineProperty(gen, "nextCallId", "nextCallId = nextCallId+1;return nextCallId;", null); 78 | defineProperty(gen, "dispatcher", "return dispatcher;", null); 79 | 80 | endFunction(gen, false, false); 81 | 82 | // --- end --- 83 | // definition of the Karura Wrapper javascript function 84 | 85 | // --- start --- 86 | // definition of the Karura Wrapper javascript prototype 87 | 88 | startPrototype(gen, FrameworkConfig.FRAMEWORK_JS_CLASS_NAME); 89 | 90 | for (String pluginName : pluginMap.keySet()) { 91 | 92 | startMemberFunction(gen, true, pluginName); 93 | defineVariable(gen, "instance = new " + PluginGenerator.jsWrapperNameForPlugin(pluginName) + "(this)"); 94 | startMemberFunction(gen, false, FrameworkConfig.FRAMEWORK_JS_CLASS_NAME + ".prototype." + pluginName); 95 | gen.addLine("return instance;"); 96 | endFunction(gen, true, false); 97 | gen.addLine("return instance;"); 98 | endFunction(gen, false, true); 99 | 100 | } 101 | 102 | addExportedMethodsForClass(gen, "window." + FrameworkConfig.FRAMEWORK_JS_HANDLE, FrameworkConfig.FRAMEWORK_JS_CLASS_NAME, FrameworkConfig.FRAMEWORK_JS_CLASS_NAME); 103 | 104 | endPrototype(gen); 105 | 106 | // -- end of prototype for the facade function 107 | 108 | gen.addLine("exports." + FrameworkConfig.FRAMEWORK_JS_CLASS_NAME + " = " + FrameworkConfig.FRAMEWORK_JS_CLASS_NAME + ";"); 109 | 110 | endAnonymousSelfExecutingFunction(gen); 111 | 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/com/karura/framework/ui/SplashActivity.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | package com.karura.framework.ui; 23 | 24 | import android.app.Activity; 25 | import android.content.Intent; 26 | import android.os.Bundle; 27 | import android.view.Window; 28 | import android.widget.Toast; 29 | 30 | import com.karura.framework.Constants; 31 | import com.karura.framework.KaruraApp; 32 | import com.karura.framework.PluginManager; 33 | import com.karura.framework.R; 34 | import com.karura.framework.config.LoaderFactory; 35 | 36 | /** 37 | * This is the splash screen for your application. Subclass this screen and the splash layout for your application. Make sure the layout 38 | * file is called splash.xml in your project 39 | * 40 | * @author nitin 41 | * 42 | */ 43 | public abstract class SplashActivity extends Activity implements Constants, PluginManager.Callback { 44 | 45 | @Override 46 | public void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | requestWindowFeature(Window.FEATURE_NO_TITLE); 49 | setContentView(R.layout.splash); 50 | 51 | /* 52 | * Run the initialization task in background 53 | */ 54 | new Thread(new Runnable() { 55 | public void run() { 56 | doStuffInBackground(); 57 | } 58 | }).start(); 59 | } 60 | 61 | /** 62 | * Returns the reference to the next intent to be launched when the splash screen is to be closed. 63 | * 64 | * Override this method to return an appropriate intent 65 | * 66 | * TODO if the app is running then we have to simply move to the next intent 67 | * 68 | * @return intent for the activity to be started 69 | */ 70 | protected Intent getNextIntent() { 71 | Intent intent = new Intent(getApplicationContext(), KaruraActivity.class); 72 | return intent; 73 | } 74 | 75 | /** 76 | * Perform the application initialization tasks in background. Currently we are loading the framework configuration and initializing the 77 | * web plugin manager. 78 | */ 79 | protected void doStuffInBackground() { 80 | KaruraApp app = KaruraApp.getApp(); 81 | app.setAppConfig(LoaderFactory.getLoader(true, getApplicationContext()).loadConfig()); 82 | app.setPluginManager(new PluginManager(getApplicationContext(), this, app.getAppConfig().pluginPackagePaths())); 83 | } 84 | 85 | /** 86 | * Override this method to perform any additional initialization in the background. If you override this method make sure you call 87 | * super.nextStep in your code. If your initialization is asynchronous then call finalStep() after your initialization is complete to 88 | * move the application main activity 89 | */ 90 | protected void nextStep() { 91 | finalStep(); 92 | } 93 | 94 | /** 95 | * Close the splash screen and start the following activity 96 | */ 97 | protected void finalStep() { 98 | /* 99 | * Continue the UI thread to the next activity 100 | */ 101 | runOnUiThread(new Runnable() { 102 | public void run() { 103 | startNextActivity(); 104 | finish(); 105 | } 106 | }); 107 | } 108 | 109 | /** 110 | * Start the next activity in the initialization chain. 111 | */ 112 | private void startNextActivity() { 113 | startActivity(getNextIntent()); 114 | } 115 | 116 | /** 117 | * Callback method from the PluginManager, which is called when the framework has been successfully initialized 118 | */ 119 | @Override 120 | public void onReady() { 121 | nextStep(); 122 | } 123 | 124 | /** 125 | * This method is called when the pluginManager could not be successfully initialzied. Show an appropriate error dialog message 126 | */ 127 | @Override 128 | public void onInternalError() { 129 | 130 | runOnUiThread(new Runnable() { 131 | public void run() { 132 | Toast.makeText(getApplicationContext(), R.string.msg_error_initializing, Toast.LENGTH_LONG).show(); 133 | finish(); 134 | } 135 | }); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /autogen/com/karura/autogen/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.karura.autogen.utils; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | public class StringUtils { 25 | 26 | public static final String LINE_SEPARATOR = getSystemProperty("line.separator"); 27 | 28 | private static String getSystemProperty(String property) { 29 | try { 30 | return System.getProperty(property); 31 | } catch (SecurityException ex) { 32 | // we are not allowed to look at this property 33 | System.err.println("Caught a SecurityException reading the system property '" + property 34 | + "'; the SystemUtils property value will default to null."); 35 | return null; 36 | } 37 | } 38 | 39 | /** 40 | *

                  41 | * Wraps a single line of text, identifying words by ' '. 42 | *

                  43 | * 44 | *

                  45 | * Leading spaces on a new line are stripped. Trailing spaces are not stripped. 46 | *

                  47 | * 48 | *
                   49 | 	 * WordUtils.wrap(null, *, *, *) = null
                   50 | 	 * WordUtils.wrap("", *, *, *) = ""
                   51 | 	 * 
                  52 | * 53 | * @param str 54 | * the String to be word wrapped, may be null 55 | * @param wrapLength 56 | * the column to wrap the words at, less than 1 is treated as 1 57 | * @param newLineStr 58 | * the string to insert for a new line, null uses the system property line separator 59 | * @param wrapLongWords 60 | * true if long words (such as URLs) should be wrapped 61 | * @return a line with newlines inserted, null if null input 62 | */ 63 | public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) { 64 | if (str == null) { 65 | return null; 66 | } 67 | if (newLineStr == null) { 68 | newLineStr = LINE_SEPARATOR; 69 | } 70 | if (wrapLength < 1) { 71 | wrapLength = 1; 72 | } 73 | int inputLineLength = str.length(); 74 | int offset = 0; 75 | StringBuffer wrappedLine = new StringBuffer(inputLineLength + 32); 76 | 77 | while ((inputLineLength - offset) > wrapLength) { 78 | if (str.charAt(offset) == ' ') { 79 | offset++; 80 | continue; 81 | } 82 | int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset); 83 | 84 | if (spaceToWrapAt >= offset) { 85 | // normal case 86 | wrappedLine.append(str.substring(offset, spaceToWrapAt)); 87 | wrappedLine.append(newLineStr); 88 | offset = spaceToWrapAt + 1; 89 | 90 | } else { 91 | // really long word or URL 92 | if (wrapLongWords) { 93 | // wrap really long word one line at a time 94 | wrappedLine.append(str.substring(offset, wrapLength + offset)); 95 | wrappedLine.append(newLineStr); 96 | offset += wrapLength; 97 | } else { 98 | // do not wrap really long word, just extend beyond limit 99 | spaceToWrapAt = str.indexOf(' ', wrapLength + offset); 100 | if (spaceToWrapAt >= 0) { 101 | wrappedLine.append(str.substring(offset, spaceToWrapAt)); 102 | wrappedLine.append(newLineStr); 103 | offset = spaceToWrapAt + 1; 104 | } else { 105 | wrappedLine.append(str.substring(offset)); 106 | offset = inputLineLength; 107 | } 108 | } 109 | } 110 | } 111 | 112 | // Whatever is left in line is short enough to just pass through 113 | wrappedLine.append(str.substring(offset)); 114 | 115 | return wrappedLine.toString(); 116 | } 117 | 118 | public static String join(String pivot, String... args) { 119 | StringBuffer sb = new StringBuffer(); 120 | int index = 0; 121 | if (args != null) { 122 | for (String arg : args) { 123 | sb.append(arg); 124 | if (index < args.length - 1) { 125 | sb.append(pivot); 126 | } 127 | index++; 128 | } 129 | } 130 | return sb.toString(); 131 | } 132 | 133 | public static boolean isEmpty(CharSequence str) { 134 | if (str == null || str.length() == 0) 135 | return true; 136 | else 137 | return false; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /assets/karura/js/framework/object_map.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | ;(function(window, document, undefined) { 23 | 'use strict'; 24 | 25 | var exports = window.exports; 26 | var debug = window.debug; 27 | 28 | function ObjectMap() { 29 | // Make sure some one is not able to apply this function to any arbitary closure 30 | if (!(this instanceof ObjectMap)) { 31 | return new ObjectMap(); 32 | } 33 | 34 | /* 35 | * Singleton, we are redefining the function in the following code so that all 36 | * subsequent calls to this function get is the current intance, but there is 37 | * no-reinitialization of the map and the getter setter properties 38 | */ 39 | var instance = this; 40 | ObjectMap = function() { 41 | debug.info('[ObjectMap] singleton instance being returned'); 42 | return instance; 43 | }; 44 | 45 | debug.info('[ObjectMap] constructor called'); 46 | 47 | var map = {}; 48 | 49 | /* 50 | * Getters/Setters 51 | */ 52 | Object.defineProperties(this, { 53 | map : { 54 | get : function() { 55 | return map; 56 | }, 57 | set : function(val) { 58 | map = val; 59 | } 60 | } 61 | }); 62 | } 63 | 64 | /* 65 | * Public APIs 66 | */ 67 | ObjectMap.prototype = { 68 | constructor : ObjectMap, 69 | 70 | VERSION : '1.0', 71 | 72 | /** 73 | * Call this function to cache an object 74 | * @param objOrId The object or Id of the object which needs to be cached. If two arguments 75 | * passed to this method then this is the id, else this is an object which must have a getId 76 | * member for us to retrieve the object id 77 | * 78 | * @param obj If this argument is present then this is the reference to the object to be cached 79 | */ 80 | add : function(objOrId) { 81 | var id, _obj; 82 | 83 | switch (arguments.length) { 84 | case 1: 85 | _obj = objOrId; 86 | id = objOrId.getId(); 87 | break; 88 | case 2: 89 | id = arguments[0]; 90 | _obj = arguments[1]; 91 | break; 92 | default: 93 | debug.error('[ObjectMap] add was called incorrectly. Ignored.'); 94 | return; 95 | } 96 | 97 | debug.log('[ObjectMap] add called with ObjectId ' + id); 98 | 99 | if (id) { 100 | return !!(this.map[id] = _obj); 101 | } 102 | }, 103 | 104 | /** 105 | * Remove the object from object cache 106 | * @param objOrId The object or Id of the object which needs to be removed. If two arguments 107 | * passed to this method then this is the id, else this is an object which must have a getId 108 | * member for us to retrieve the object id 109 | * 110 | * @param obj If this argument is present then this is the reference to the object to be removed 111 | */ 112 | remove : function(objOrId) { 113 | var id, _obj; 114 | 115 | switch (arguments.length) { 116 | case 1: 117 | _obj = objOrId; 118 | id = objOrId.getId(); 119 | break; 120 | case 2: 121 | id = arguments[0]; 122 | _obj = arguments[1]; 123 | break; 124 | default: 125 | debug.error('[ObjectMap] remove was called incorrectly. Ignored.'); 126 | return; 127 | } 128 | 129 | if (id) { 130 | this.map[id] = null; 131 | delete this.map[id]; 132 | return true; 133 | } 134 | 135 | return false; 136 | }, 137 | 138 | /** 139 | * Retrieve a cached object 140 | * @param id The id of the object which needs to be fetched 141 | */ 142 | getById : function(id) { 143 | debug.log('[ObjectMap] getById called with ObjectId ' + id); 144 | return this.map[id]; 145 | }, 146 | 147 | toString : function() { 148 | return '[ObjectMap]'; 149 | } 150 | }; 151 | 152 | /* 153 | * Make this class final 154 | */ 155 | (Object.freeze||Object)(ObjectMap.prototype); 156 | 157 | /* 158 | * Make this class accessible in the exports namespace 159 | */ 160 | exports.add('ObjectMap', ObjectMap); 161 | }(window, document)); 162 | -------------------------------------------------------------------------------- /src/com/karura/framework/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | 23 | /** 24 | This file derived from Apache Commons Project available under the Apache 2.0 License 25 | Please refer to APACHE-LICENCE2.0.txt for attributions 26 | */ 27 | 28 | package com.karura.framework.utils; 29 | 30 | public class StringUtils { 31 | 32 | public static final String LINE_SEPARATOR = getSystemProperty("line.separator"); 33 | 34 | private static String getSystemProperty(String property) { 35 | try { 36 | return System.getProperty(property); 37 | } catch (SecurityException ex) { 38 | // we are not allowed to look at this property 39 | System.err.println("Caught a SecurityException reading the system property '" + property + "'; the SystemUtils property value will default to null."); 40 | return null; 41 | } 42 | } 43 | 44 | /** 45 | *

                  46 | * Wraps a single line of text, identifying words by ' '. 47 | *

                  48 | * 49 | *

                  50 | * Leading spaces on a new line are stripped. Trailing spaces are not stripped. 51 | *

                  52 | * 53 | *
                   54 | 	 * WordUtils.wrap(null, *, *, *) = null
                   55 | 	 * WordUtils.wrap("", *, *, *) = ""
                   56 | 	 * 
                  57 | * 58 | * @param str 59 | * the String to be word wrapped, may be null 60 | * @param wrapLength 61 | * the column to wrap the words at, less than 1 is treated as 1 62 | * @param newLineStr 63 | * the string to insert for a new line, null uses the system property line separator 64 | * @param wrapLongWords 65 | * true if long words (such as URLs) should be wrapped 66 | * @return a line with newlines inserted, null if null input 67 | */ 68 | public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) { 69 | if (str == null) { 70 | return null; 71 | } 72 | if (newLineStr == null) { 73 | newLineStr = LINE_SEPARATOR; 74 | } 75 | if (wrapLength < 1) { 76 | wrapLength = 1; 77 | } 78 | int inputLineLength = str.length(); 79 | int offset = 0; 80 | StringBuffer wrappedLine = new StringBuffer(inputLineLength + 3); 81 | 82 | while ((inputLineLength - offset) > wrapLength) { 83 | if (str.charAt(offset) == ' ') { 84 | offset++; 85 | continue; 86 | } 87 | int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset); 88 | 89 | if (spaceToWrapAt >= offset) { 90 | // normal case 91 | wrappedLine.append(str.substring(offset, spaceToWrapAt)); 92 | wrappedLine.append(newLineStr); 93 | offset = spaceToWrapAt + 1; 94 | 95 | } else { 96 | // really long word or URL 97 | if (wrapLongWords) { 98 | // wrap really long word one line at a time 99 | wrappedLine.append(str.substring(offset, wrapLength + offset)); 100 | wrappedLine.append(newLineStr); 101 | offset += wrapLength; 102 | } else { 103 | // do not wrap really long word, just extend beyond limit 104 | spaceToWrapAt = str.indexOf(' ', wrapLength + offset); 105 | if (spaceToWrapAt >= 0) { 106 | wrappedLine.append(str.substring(offset, spaceToWrapAt)); 107 | wrappedLine.append(newLineStr); 108 | offset = spaceToWrapAt + 1; 109 | } else { 110 | wrappedLine.append(str.substring(offset)); 111 | offset = inputLineLength; 112 | } 113 | } 114 | } 115 | } 116 | 117 | // Whatever is left in line is short enough to just pass through 118 | wrappedLine.append(str.substring(offset)); 119 | 120 | return wrappedLine.toString(); 121 | } 122 | 123 | public static String join(String pivot, String... args) { 124 | StringBuffer sb = new StringBuffer(); 125 | int index = 0; 126 | if (args != null) { 127 | for (String arg : args) { 128 | sb.append(arg); 129 | if (index < args.length - 1) { 130 | sb.append(pivot); 131 | } 132 | index++; 133 | } 134 | } 135 | return sb.toString(); 136 | } 137 | 138 | public static String capitalize(final String str) { 139 | 140 | if (str == null || str.length() == 0) { 141 | return str; 142 | } 143 | final char[] buffer = str.toCharArray(); 144 | buffer[0] = Character.toTitleCase(buffer[0]); 145 | return new String(buffer); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/utils/DirectoryManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | package com.karura.framework.plugins.utils; 27 | 28 | import java.io.File; 29 | 30 | import android.content.Context; 31 | import android.os.Environment; 32 | import android.os.StatFs; 33 | 34 | /** 35 | * This class provides file directory utilities. All file operations are performed on the SD card. 36 | * 37 | * It is used by the FileUtils class. 38 | */ 39 | public class DirectoryManager { 40 | 41 | @SuppressWarnings("unused") 42 | private static final String LOG_TAG = "DirectoryManager"; 43 | 44 | /** 45 | * Determine if a file or directory exists. 46 | * 47 | * @param name 48 | * The name of the file to check. 49 | * @return T=exists, F=not found 50 | */ 51 | protected static boolean testFileExists(String name) { 52 | boolean status; 53 | 54 | // If SD card exists 55 | if ((testSaveLocationExists()) && (!name.equals(""))) { 56 | File path = Environment.getExternalStorageDirectory(); 57 | File newPath = constructFilePaths(path.toString(), name); 58 | status = newPath.exists(); 59 | } 60 | // If no SD card 61 | else { 62 | status = false; 63 | } 64 | return status; 65 | } 66 | 67 | /** 68 | * Get the free disk space 69 | * 70 | * @return Size in KB or -1 if not available 71 | */ 72 | protected static long getFreeDiskSpace(boolean checkInternal) { 73 | String status = Environment.getExternalStorageState(); 74 | long freeSpace = 0; 75 | 76 | // If SD card exists 77 | if (status.equals(Environment.MEDIA_MOUNTED)) { 78 | freeSpace = freeSpaceCalculation(Environment.getExternalStorageDirectory().getPath()); 79 | } else if (checkInternal) { 80 | freeSpace = freeSpaceCalculation("/"); 81 | } 82 | // If no SD card and we haven't been asked to check the internal directory then return -1 83 | else { 84 | return -1; 85 | } 86 | 87 | return freeSpace; 88 | } 89 | 90 | /** 91 | * Given a path return the number of free KB 92 | * 93 | * @param path 94 | * to the file system 95 | * @return free space in KB 96 | */ 97 | private static long freeSpaceCalculation(String path) { 98 | StatFs stat = new StatFs(path); 99 | long blockSize = stat.getBlockSize(); 100 | long availableBlocks = stat.getAvailableBlocks(); 101 | return availableBlocks * blockSize / 1024; 102 | } 103 | 104 | /** 105 | * Determine if SD card exists. 106 | * 107 | * @return T=exists, F=not found 108 | */ 109 | protected static boolean testSaveLocationExists() { 110 | String sDCardStatus = Environment.getExternalStorageState(); 111 | boolean status; 112 | 113 | // If SD card is mounted 114 | if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) { 115 | status = true; 116 | } 117 | 118 | // If no SD card 119 | else { 120 | status = false; 121 | } 122 | return status; 123 | } 124 | 125 | /** 126 | * Create a new file object from two file paths. 127 | * 128 | * @param file1 129 | * Base file path 130 | * @param file2 131 | * Remaining file path 132 | * @return File object 133 | */ 134 | private static File constructFilePaths(String file1, String file2) { 135 | File newPath; 136 | if (file2.startsWith(file1)) { 137 | newPath = new File(file2); 138 | } else { 139 | newPath = new File(file1 + "/" + file2); 140 | } 141 | return newPath; 142 | } 143 | 144 | /** 145 | * Determine if we can use the SD Card to store the temporary file. If not then use the internal cache directory. 146 | * 147 | * @return the absolute path of where to store the file 148 | */ 149 | public static String getTempDirectoryPath(Context ctx) { 150 | File cache = null; 151 | 152 | // SD Card Mounted 153 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 154 | cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + ctx.getPackageName() + "/cache/"); 155 | } 156 | // Use internal storage 157 | else { 158 | cache = ctx.getCacheDir(); 159 | } 160 | 161 | // Create the cache directory if it doesn't exist 162 | if (!cache.exists()) { 163 | cache.mkdirs(); 164 | } 165 | 166 | return cache.getAbsolutePath(); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /autogen/com/karura/autogen/codegen/AbsCodeGenerator.java: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | ============== GPL License ============== 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | 18 | ============== Commercial License============== 19 | https://github.com/karuradev/licenses/blob/master/toc.txt 20 | */ 21 | 22 | package com.karura.autogen.codegen; 23 | 24 | import com.karura.autogen.BuildConfig; 25 | import com.karura.autogen.utils.SourceBuffer; 26 | import com.karura.autogen.utils.StringUtils; 27 | import com.karura.framework.FrameworkConfig; 28 | 29 | public abstract class AbsCodeGenerator { 30 | public abstract void applyToBuffer(SourceBuffer gen); 31 | 32 | protected void startFunction(SourceBuffer gen, boolean isStrict, String functionName, String... args) { 33 | StringBuffer sb = new StringBuffer(); 34 | 35 | sb.append("function "); 36 | if (functionName != null) { 37 | sb.append(functionName); 38 | } 39 | sb.append("("); 40 | sb.append(StringUtils.join(",", args)); 41 | sb.append(") "); 42 | 43 | gen.sB(sb.toString()); 44 | if (isStrict) { 45 | gen.addLine("'use strict';"); 46 | } 47 | } 48 | 49 | protected void startMemberFunction(SourceBuffer gen, boolean jsonNotation, String functionName, String... args) { 50 | StringBuffer sb = new StringBuffer(); 51 | 52 | if (functionName == null) { 53 | throw new IllegalArgumentException(); 54 | } 55 | 56 | sb.append(functionName); 57 | 58 | if (jsonNotation) { 59 | sb.append(" : "); 60 | } else { 61 | sb.append(" = "); 62 | } 63 | 64 | sb.append("function "); 65 | 66 | sb.append("("); 67 | sb.append(StringUtils.join(",", args)); 68 | sb.append(") "); 69 | 70 | gen.sB(sb.toString()); 71 | } 72 | 73 | protected void endFunction(SourceBuffer gen, boolean useSemi, boolean useComma) { 74 | if (useSemi && useComma) { 75 | throw new IllegalArgumentException(); 76 | } 77 | if (useSemi) { 78 | gen.eBwithSemi(); 79 | } else if (useComma) { 80 | gen.eBWithComma(); 81 | } else { 82 | gen.eB(); 83 | } 84 | } 85 | 86 | protected void startAnonymousSelfExecutingFunction(SourceBuffer gen, boolean isStrict) { 87 | 88 | addComment(gen, "---- framework javascript begins"); 89 | addComment(gen, "undefined is passed to restore the definition of undefined incase it has been overridden"); 90 | 91 | gen.addLine("; ("); 92 | startFunction(gen, isStrict, null, "window", "document", "undefined"); 93 | } 94 | 95 | protected void endAnonymousSelfExecutingFunction(SourceBuffer gen) { 96 | gen.eB(); 97 | gen.addLine("(window, document));"); 98 | } 99 | 100 | protected void defineVariable(SourceBuffer gen, String... variables) { 101 | StringBuffer sb = new StringBuffer("var "); 102 | sb.append(StringUtils.join(",", variables)); 103 | sb.append(";"); 104 | gen.addLine(sb.toString()); 105 | } 106 | 107 | protected void defineProperty(SourceBuffer gen, String propertyName, String propBodyGet, String propBodySet) { 108 | gen.sB("Object.defineProperty(this, '" + propertyName + "',"); 109 | if (propBodyGet != null) { 110 | gen.sB("get : function()"); 111 | gen.addLine(propBodyGet); 112 | gen.eBWithComma(); 113 | } 114 | 115 | if (propBodySet != null) { 116 | gen.sB("set : function()"); 117 | gen.addLine(propBodySet); 118 | gen.eBWithComma(); 119 | } 120 | 121 | gen.eB(); 122 | gen.addLine(");"); 123 | } 124 | 125 | protected void startPrototype(SourceBuffer gen, String className) { 126 | gen.sB(className + ".prototype = "); 127 | gen.addLine("constructor : " + className + ","); 128 | gen.addLine("version : '" + FrameworkConfig.FRAMEWORK_VERSION + "',"); 129 | } 130 | 131 | protected void endPrototype(SourceBuffer gen) { 132 | gen.eBwithSemi(); 133 | } 134 | 135 | protected void addComment(SourceBuffer gen, String desc) { 136 | if (BuildConfig.DEBUG) { 137 | if (!StringUtils.isEmpty(desc)) { 138 | String[] comps = StringUtils.wrap(desc, 80, StringUtils.LINE_SEPARATOR, false).split(StringUtils.LINE_SEPARATOR); 139 | for (String comp : comps) { 140 | gen.addLine("//" + comp); 141 | } 142 | } 143 | } 144 | } 145 | 146 | protected void addMultiComment(SourceBuffer gen, String desc, boolean begin, boolean end) { 147 | if (BuildConfig.DEBUG) { 148 | if (begin) { 149 | gen.addLine("/*"); 150 | } 151 | if (!StringUtils.isEmpty(desc)) { 152 | String[] comps = StringUtils.wrap(desc, 80, StringUtils.LINE_SEPARATOR, false).split(StringUtils.LINE_SEPARATOR); 153 | for (String comp : comps) { 154 | gen.addLine("*" + comp); 155 | } 156 | } 157 | 158 | if (end) { 159 | gen.addLine("*/"); 160 | } 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/com/karura/framework/plugins/Device.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | package com.karura.framework.plugins; 28 | 29 | import static android.provider.Settings.Secure.ANDROID_ID; 30 | 31 | import java.util.TimeZone; 32 | 33 | import org.json.JSONException; 34 | import org.json.JSONObject; 35 | 36 | import android.os.Bundle; 37 | import android.provider.Settings; 38 | import android.webkit.JavascriptInterface; 39 | 40 | import com.karura.framework.PluginManager; 41 | import com.karura.framework.annotations.Description; 42 | import com.karura.framework.annotations.ExportToJs; 43 | import com.karura.framework.annotations.JavascriptModule; 44 | import com.karura.framework.annotations.SupportJavascriptInterface; 45 | import com.karura.framework.annotations.Synchronous; 46 | import com.karura.framework.ui.webview.KaruraWebView; 47 | 48 | @JavascriptModule 49 | @Description("Plugin can be used to query device specific parameters") 50 | public class Device extends WebViewPlugin { 51 | 52 | private static String platform = "Android"; // Device OS 53 | private static String uuid; // Device UUID 54 | 55 | @ExportToJs 56 | @Description("Field which will contain device UUID") 57 | private static final String UUID_FIELD = "uuid"; 58 | 59 | @ExportToJs 60 | @Description("Field for returning the platform version") 61 | private static final String PLATFORM_VERSION_FIELD = "version"; 62 | 63 | @ExportToJs 64 | @Description("Field for returning platform name") 65 | private static final String PLATFORM_FIELD = "platform"; 66 | 67 | @ExportToJs 68 | @Description("Field for return device name") 69 | private static final String DEVICE_NAME_FIELD = "name"; 70 | 71 | @ExportToJs 72 | @Description("Field for returning device model") 73 | private static final String DEVICE_MODEL_FIELD = "model"; 74 | 75 | protected Device(int pluginId, PluginManager pluginManager, KaruraWebView webView, Bundle savedInstance) { 76 | super(pluginId, pluginManager, webView, savedInstance); 77 | uuid = getUuid(); 78 | } 79 | 80 | /** 81 | * Executes the request and returns PluginResult. 82 | * 83 | * @param action 84 | * The action to execute. 85 | * @param args 86 | * JSONArry of arguments for the plugin. 87 | * @param callbackContext 88 | * The callback id used when calling back into JavaScript. 89 | * @return True if the action was valid, false if not. 90 | */ 91 | @Synchronous(retVal = "Returns the stringified json object containing device params ") 92 | @Description("Fetch device specific details") 93 | @JavascriptInterface 94 | @SupportJavascriptInterface 95 | public String getDeviceInfo() { 96 | 97 | try { 98 | JSONObject r = new JSONObject(); 99 | r.put(UUID_FIELD, Device.uuid); 100 | r.put(PLATFORM_VERSION_FIELD, this.getOSVersion()); 101 | r.put(PLATFORM_FIELD, Device.platform); 102 | r.put(DEVICE_NAME_FIELD, this.getProductName()); 103 | r.put(DEVICE_MODEL_FIELD, this.getModel()); 104 | 105 | return r.toString(); 106 | } catch (JSONException e) { 107 | // should never hapen 108 | } 109 | return null; 110 | } 111 | 112 | // -------------------------------------------------------------------------- 113 | // LOCAL METHODS 114 | // -------------------------------------------------------------------------- 115 | 116 | /** 117 | * Get the OS name. 118 | * 119 | * @return 120 | */ 121 | public String getPlatform() { 122 | return Device.platform; 123 | } 124 | 125 | /** 126 | * Get the device's Universally Unique Identifier (UUID). 127 | * 128 | * @return 129 | */ 130 | public String getUuid() { 131 | String uuid = Settings.Secure.getString(getContext().getContentResolver(), ANDROID_ID); 132 | return uuid; 133 | } 134 | 135 | public String getModel() { 136 | String model = android.os.Build.MODEL; 137 | return model; 138 | } 139 | 140 | public String getProductName() { 141 | String productname = android.os.Build.PRODUCT; 142 | return productname; 143 | } 144 | 145 | /** 146 | * Get the OS version. 147 | * 148 | * @return 149 | */ 150 | public String getOSVersion() { 151 | String osversion = android.os.Build.VERSION.RELEASE; 152 | return osversion; 153 | } 154 | 155 | public String getSDKVersion() { 156 | String sdkversion = String.valueOf(android.os.Build.VERSION.SDK_INT); 157 | return sdkversion; 158 | } 159 | 160 | public String getTimeZoneID() { 161 | TimeZone tz = TimeZone.getDefault(); 162 | return (tz.getID()); 163 | } 164 | 165 | @Override 166 | public void onSaveInstanceState(Bundle saveInInstance) { 167 | // TODO Auto-generated method stub 168 | 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/src/object.js: -------------------------------------------------------------------------------- 1 | // vi:ts=2 sw=2 expandtab 2 | 3 | /** 4 | * Create a mockable and stubbable objects. 5 | * 6 | *

                  A mock is created with a object prototype as an argument, or with a constructor 7 | * (which will be called with no arguments to construct a prototype). Once 8 | * created, the mock object will have all the same methods as the prototype. These 9 | * methods, when invoked, will return undefined by default.

                  10 | * 11 | *

                  Note: If a constructor is provided, it will be called with no 12 | * arguments. Be careful not to pass constructors that will modify the 13 | * state of the application when invoked!. And if you're mocking objects that 14 | * require arguments to the constructor then you must create an instance 15 | * first and supply that instance as a prototype.

                  16 | * 17 | *

                  Stub declarations may then be made for these methods to have them return 18 | * useful values or perform actions when invoked.

                  19 | * 20 | *
                   21 |  * MyObject = function() {
                   22 |  *   this.add = function(a, b) { return a + b }
                   23 |  * };
                   24 |  *
                   25 |  * var mockObj = JsMockito.mock(MyObject);
                   26 |  * mockObj.add(5, 4); // result is undefined
                   27 |  *
                   28 |  * JsMockito.when(mockFunc).add(1, 2).thenReturn(6);
                   29 |  * mockObj.add(1, 2); // result is 6
                   30 |  *
                   31 |  * JsMockito.verify(mockObj).add(1, greaterThan(2)); // ok
                   32 |  * JsMockito.verify(mockObj).add(1, equalTo(2)); // ok
                   33 |  * JsMockito.verify(mockObj).add(1, 4); // will throw an exception
                   34 |  * 
                  35 | * 36 | * Alternatively, using a prototype: 37 | * 38 | *
                   39 |  * myPrototype = {
                   40 |  *   add: function(a, b) { return a + b }
                   41 |  * };
                   42 |  *
                   43 |  * var mockObj = JsMockito.mock(myPrototype);
                   44 |  * mockObj.add(5, 4); // result is undefined
                   45 |  * 
                  46 | * 47 | * @param Obj {function} the constructor for the object to be mocked 48 | * @return {object} a mock object 49 | */ 50 | JsMockito.mock = function(Obj, delegate) { 51 | delegate = delegate || {}; 52 | 53 | var MockObject = function() { }; 54 | try { 55 | MockObject.prototype = (typeof Obj === "function")? new Obj : Obj; 56 | } catch (e) { 57 | throw new Error("mocked constructor threw an exception (consider mocking an object instead of a constructor)"); 58 | } 59 | MockObject.prototype.constructor = MockObject; 60 | 61 | var mockObject = new MockObject(); 62 | var stubBuilders = {}; 63 | var verifiers = {}; 64 | var mockFunctions = []; 65 | 66 | var contextMatcher = JsHamcrest.Matchers.sameAs(mockObject); 67 | 68 | var addMockMethod = function(name) { 69 | var delegateMethod; 70 | if (delegate[name] != undefined) { 71 | delegateMethod = function() { 72 | var context = (this == mockObject)? delegate : this; 73 | return delegate[name].apply(context, arguments); 74 | }; 75 | } 76 | var mockFunc = JsMockito.mockFunction('obj.' + name, delegateMethod); 77 | var desc = JsMockito.propertyDescriptor(mockObject, name); 78 | var enumerable = desc? desc.enumerable : true; 79 | 80 | JsMockito.defineProperty(mockObject, name, { 81 | enumerable: enumerable, 82 | writable: true, 83 | configurable: true, 84 | value: mockFunc 85 | }); 86 | stubBuilders[name] = { 87 | enumerable: enumerable, 88 | value: mockFunc._jsMockitoStubBuilder 89 | }; 90 | verifiers[name] = { 91 | enumerable: enumerable, 92 | value: mockFunc._jsMockitoVerifier 93 | }; 94 | mockFunctions.push(mockFunc); 95 | }; 96 | 97 | JsMockito.each(JsMockito.propertyNames(mockObject), function(name) { 98 | if (name == 'constructor') 99 | return; 100 | if (typeof mockObject[name] === 'function') 101 | addMockMethod(name); 102 | else if (delegate[name] != undefined) { 103 | if (Object.defineProperty) { 104 | Object.defineProperty(mockObject, name, { 105 | get: function() { return delegate[name] }, 106 | set: function(val) { delegate[name] = val } 107 | }); 108 | } else { 109 | mockObject[name] = delegate[name]; 110 | } 111 | } 112 | }); 113 | 114 | for (var typeName in JsMockito.nativeTypes) { 115 | if (mockObject instanceof JsMockito.nativeTypes[typeName].type) { 116 | JsMockito.each(JsMockito.nativeTypes[typeName].methods, function(method) { 117 | addMockMethod(method); 118 | }); 119 | } 120 | } 121 | 122 | JsMockito.defineProperty(mockObject, '_jsMockitoStubBuilder', { 123 | enumerable: false, 124 | value: function() { 125 | var stubBuilderObj = new MockObject(); 126 | JsMockito.eachObject(stubBuilders, function(desc, name) { 127 | JsMockito.overwriteProperty(stubBuilderObj, name, { 128 | enumerable: desc.enumerable, 129 | value: desc.value.call(this, contextMatcher) 130 | }); 131 | }); 132 | return stubBuilderObj; 133 | } 134 | }); 135 | 136 | JsMockito.defineProperty(mockObject, '_jsMockitoVerifier', { 137 | enumerable: false, 138 | value: function(verifier) { 139 | var verifierObj = new MockObject(); 140 | JsMockito.eachObject(verifiers, function(desc, name) { 141 | JsMockito.overwriteProperty(verifierObj, name, { 142 | enumerable: desc.enumerable, 143 | value: desc.value.call(this, verifier, contextMatcher) 144 | }); 145 | }); 146 | return verifierObj; 147 | } 148 | }); 149 | 150 | JsMockito.defineProperty(mockObject, '_jsMockitoMockFunctions', { 151 | enumerable: false, 152 | value: function() { 153 | return mockFunctions; 154 | } 155 | }); 156 | 157 | return mockObject; 158 | }; 159 | JsMockito._export.push('mock'); 160 | -------------------------------------------------------------------------------- /autogen/com/karura/autogen/Main.java: -------------------------------------------------------------------------------- 1 | package com.karura.autogen; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.io.File; 25 | import java.io.FileInputStream; 26 | import java.io.FileOutputStream; 27 | import java.net.URL; 28 | import java.util.HashMap; 29 | import java.util.jar.JarEntry; 30 | import java.util.jar.JarInputStream; 31 | 32 | import com.karura.autogen.codegen.FrameworkGenerator; 33 | import com.karura.autogen.utils.SourceBuffer; 34 | import com.karura.framework.FrameworkConfig; 35 | import com.karura.framework.PluginManager; 36 | import com.karura.framework.annotations.JavascriptModule; 37 | import com.karura.framework.config.LoaderFactory; 38 | import com.karura.framework.plugins.WebViewPlugin; 39 | import com.karura.framework.config.ConfigLoader; 40 | import com.karura.framework.config.ConfigStore; 41 | 42 | public class Main { 43 | public static void printUsage(String... message) { 44 | System.err.println("Karura script autogenerator"); 45 | System.err.println("---------------------------------------------"); 46 | System.err.println("java -jar autogen.jar [karura_jar] [config_file_path] [output_folder] [generate_comments]"); 47 | System.err.println("karura_jar : Path to karura jar file"); 48 | System.err.println("config_file_path : path to the config file which contains framework config"); 49 | System.err.println("output_folder : Path to directory where " + FrameworkConfig.FRAMEWORK_JS_FILENAME + " needs to be generated"); 50 | System.err.println("generate_comments : Whether karura.js should include comments"); 51 | System.err.println("---------------------------------------------"); 52 | if (message.length > 0) { 53 | System.err.println("Error : " + message[0]); 54 | System.err.println("---------------------------------------------"); 55 | } 56 | } 57 | 58 | public static void main(String[] args) { 59 | 60 | if (args.length != 4) { 61 | printUsage(); 62 | return; 63 | } 64 | 65 | if (!new File(args[0]).isFile()) { 66 | printUsage("Please specify a valid path to karura.jar file."); 67 | return; 68 | } 69 | 70 | if (!new File(args[1]).isFile()){ 71 | printUsage("Please specify the framework config path. This is the config.xml file in the res folder."); 72 | } 73 | 74 | if (!new File(args[2]).isDirectory()) { 75 | printUsage("Please specify a valid output directory."); 76 | return; 77 | } 78 | 79 | BuildConfig.DEBUG = Boolean.valueOf(args[3]); 80 | 81 | 82 | String jarName = args[0]; 83 | 84 | ConfigStore cs = LoaderFactory.getLoader(false, args[1]).loadConfig(); 85 | 86 | File javascriptFile = new File(args[2], FrameworkConfig.FRAMEWORK_JS_FILENAME); 87 | 88 | FileOutputStream fos = null; 89 | System.out.println(String.format("Processing %s for plugins ", jarName)); 90 | try { 91 | HashMap> result = new HashMap>(); 92 | URL[] urls = { 93 | new URL("jar:file:" + jarName + "!/") 94 | }; 95 | 96 | JarInputStream jarFile = new JarInputStream(new FileInputStream(jarName)); 97 | JarEntry jarEntry; 98 | 99 | while (true) { 100 | jarEntry = jarFile.getNextJarEntry(); 101 | if (jarEntry == null) { 102 | break; 103 | } 104 | 105 | if (jarEntry.getName().endsWith(".class")) { 106 | String className = jarEntry.getName().substring(0, jarEntry.getName().length() - 6); 107 | className = className.replace('/', '.'); 108 | 109 | if (className.startsWith("com.karura.framework.plugins")) { 110 | Class clazz = null; 111 | try { 112 | 113 | clazz = (Class) Class.forName(className); 114 | if (!WebViewPlugin.class.isAssignableFrom(clazz)) { 115 | continue; 116 | } 117 | if (clazz.getAnnotation(JavascriptModule.class) == null) { 118 | continue; 119 | } 120 | @SuppressWarnings("unchecked") 121 | Class webViewPlugin = (Class) clazz; 122 | result.put(clazz.getSimpleName(), webViewPlugin); 123 | } catch (Exception e) { 124 | if (BuildConfig.DEBUG) { 125 | e.printStackTrace(); 126 | } 127 | if (clazz != null) { 128 | System.err.println(clazz.getSimpleName() + " was ignored due to an error"); 129 | } else { 130 | System.err.println(clazz.getSimpleName() + "Internal but recoverable error"); 131 | } 132 | } 133 | } 134 | 135 | } 136 | } 137 | 138 | SourceBuffer gen = new SourceBuffer(); 139 | new FrameworkGenerator(result).applyToBuffer(gen); 140 | 141 | System.out.println(String.format("Writing javascript to %s",javascriptFile.getAbsolutePath())); 142 | fos = new FileOutputStream(javascriptFile); 143 | fos.write(gen.toString().getBytes()); 144 | 145 | } catch (Exception e) { 146 | e.printStackTrace(); 147 | } finally { 148 | try { 149 | if (fos != null) { 150 | fos.close(); 151 | } 152 | } catch (Exception e) { 153 | e.printStackTrace(); 154 | } 155 | } 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/com/karura/framework/config/ConfigStore.java: -------------------------------------------------------------------------------- 1 | package com.karura.framework.config; 2 | 3 | /** 4 | 5 | ============== GPL License ============== 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | 20 | ============== Commercial License============== 21 | https://github.com/karuradev/licenses/blob/master/toc.txt 22 | */ 23 | 24 | import java.util.ArrayList; 25 | import java.util.HashMap; 26 | import java.util.Iterator; 27 | import java.util.List; 28 | import java.util.regex.Matcher; 29 | import java.util.regex.Pattern; 30 | 31 | import android.util.Log; 32 | 33 | import com.karura.framework.FrameworkConfig; 34 | import com.karura.framework.utils.StringUtils; 35 | 36 | public class ConfigStore extends HashMap { 37 | private static final String TAG = "Config"; 38 | private static final long serialVersionUID = 1L; 39 | 40 | ConfigStore() { 41 | super(); 42 | put("whiteList", new ArrayList()); 43 | put("startUrl", "file:///android_asset/karura/index.html"); 44 | put("whiteListCache", new HashMap()); 45 | put("pluginPaths", new ArrayList()); 46 | } 47 | 48 | @SuppressWarnings("unchecked") 49 | public List whiteList() { 50 | return (List) get("whiteList"); 51 | } 52 | 53 | @SuppressWarnings("unchecked") 54 | public List pluginPackagePaths() { 55 | return (List) get("pluginPaths"); 56 | } 57 | 58 | public String startUrl() { 59 | return (String) get("startUrl"); 60 | } 61 | 62 | public void setStartUrl(String url) { 63 | if (url != null && url.trim().length() > 0) { 64 | put("startUrl", url); 65 | } 66 | } 67 | 68 | public boolean noActivityTitle() { 69 | return (Boolean) get("no_activity_title"); 70 | } 71 | 72 | public boolean appRequiresFullScreen(){ 73 | return (Boolean)get("full_screen"); 74 | } 75 | 76 | @SuppressWarnings("unchecked") 77 | HashMap whiteListCache() { 78 | return (HashMap) get("whiteListCache"); 79 | } 80 | 81 | /** 82 | * Determine if URL is in approved list of URLs to load. 83 | * 84 | * @param url 85 | * @return 86 | */ 87 | public boolean isUrlWhiteListed(String url) { 88 | 89 | // Check to see if we have matched url previously 90 | if (whiteListCache().get(url) != null) { 91 | return true; 92 | } 93 | 94 | // Look for match in white list 95 | Iterator pit = whiteList().iterator(); 96 | while (pit.hasNext()) { 97 | Pattern p = pit.next(); 98 | Matcher m = p.matcher(url); 99 | 100 | // If match found, then cache it to speed up subsequent comparisons 101 | if (m.find()) { 102 | whiteListCache().put(url, true); 103 | return true; 104 | } 105 | } 106 | return false; 107 | } 108 | 109 | /** 110 | * Add entry to approved list of URLs (whitelist) 111 | * 112 | * @param origin 113 | * URL regular expression to allow 114 | * @param subdomains 115 | * T=include all subdomains under origin 116 | */ 117 | 118 | public void addWhitelistEntry(String origin, boolean subdomains) { 119 | try { 120 | // Unlimited access to network resources 121 | if (origin.compareTo("*") == 0) { 122 | Log.d(TAG, "Warning : Unlimited access to network resources"); 123 | whiteList().add(Pattern.compile(".*")); 124 | } else { // specific access 125 | // check if subdomains should be included 126 | // if the user has not specified any preference for URLs we will add https by default. 127 | if (subdomains) { 128 | if (origin.startsWith("http")) { 129 | whiteList().add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?"))); 130 | } else { 131 | whiteList().add(Pattern.compile("^https?://(.*\\.)?" + origin)); 132 | } 133 | Log.d(TAG, String.format("Origin to allow with subdomains: %s", origin)); 134 | } else { 135 | if (origin.startsWith("http")) { 136 | whiteList().add(Pattern.compile(origin.replaceFirst("https?://", "^https?://"))); 137 | } else { 138 | whiteList().add(Pattern.compile("^https?://" + origin)); 139 | } 140 | Log.d(TAG, String.format("Origin to allow: %s", origin)); 141 | } 142 | } 143 | } catch (Exception e) { 144 | Log.d(TAG, String.format("Failed to add origin %s", origin)); 145 | } 146 | } 147 | 148 | public void setLogLevel(String level) { 149 | put("loglevel", level); 150 | 151 | } 152 | 153 | public void setFrameworkVersion(String version) { 154 | FrameworkConfig.FRAMEWORK_VERSION = version; 155 | 156 | } 157 | 158 | public void setFrameworkName(String frameworkName) { 159 | FrameworkConfig.FRAMEWORK_NAME = frameworkName; 160 | FrameworkConfig.FRAMEWORK_JS_FILENAME = FrameworkConfig.FRAMEWORK_NAME + ".js"; 161 | FrameworkConfig.FRAMEWORK_JS_HANDLE = "_" + FrameworkConfig.FRAMEWORK_NAME + "_plugins"; 162 | FrameworkConfig.FRAMEWORK_JS_CLASS_NAME = StringUtils.capitalize(FrameworkConfig.FRAMEWORK_NAME); 163 | } 164 | 165 | public void showActivityTitle(String attributeValue) { 166 | put("no_activity_title", Boolean.valueOf(attributeValue)); 167 | 168 | } 169 | 170 | public void showActivityFullScreen(String attributeValue){ 171 | put("full_screen", Boolean.valueOf(attributeValue)); 172 | } 173 | 174 | @SuppressWarnings("unchecked") 175 | public void addPackagePath(String pkg) { 176 | ((ArrayList)get("pluginPaths")).add(pkg); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /prebuilt/jsmockito/lib/screw-unit/screw.matchers.js: -------------------------------------------------------------------------------- 1 | Screw.Matchers = (function($) { 2 | return matchers = { 3 | expect: function(actual) { 4 | return { 5 | to: function(matcher, expected, not) { 6 | var matched = matcher.match(expected, actual); 7 | if (not ? matched : !matched) { 8 | throw(matcher.failure_message(expected, actual, not)); 9 | } 10 | }, 11 | 12 | to_not: function(matcher, expected) { 13 | this.to(matcher, expected, true); 14 | } 15 | } 16 | }, 17 | 18 | equal: { 19 | match: function(expected, actual) { 20 | if(expected == actual) return true; 21 | if(actual == undefined) return false; 22 | 23 | if (expected instanceof Array) { 24 | for (var i = 0; i < actual.length; i++) 25 | if (!Screw.Matchers.equal.match(expected[i], actual[i])) return false; 26 | return actual.length == expected.length; 27 | } else if (expected instanceof Object) { 28 | for (var key in expected) 29 | if (!this.match(expected[key], actual[key])) return false; 30 | for (var key in actual) 31 | if (!this.match(actual[key], expected[key])) return false; 32 | return true; 33 | } 34 | return false; 35 | }, 36 | 37 | failure_message: function(expected, actual, not) { 38 | return 'expected ' + $.print(actual) + (not ? ' to not equal ' : ' to equal ') + $.print(expected); 39 | } 40 | }, 41 | 42 | be_gt: { 43 | match: function(expected, actual) { 44 | return actual > expected; 45 | }, 46 | 47 | failure_message: function(expected, actual, not) { 48 | return 'expected ' + $.print(actual) + (not ? ' to not ' : ' to ') + 'be greater than ' + $.print(expected); 49 | } 50 | }, 51 | 52 | be_gte: { 53 | match: function(expected, actual) { 54 | return actual >= expected; 55 | }, 56 | 57 | failure_message: function(expected, actual, not) { 58 | return 'expected ' + $.print(actual) + (not ? ' to not ' : ' to ') + 'be greater than or equal to ' + $.print(expected); 59 | } 60 | }, 61 | 62 | be_lt: { 63 | match: function(expected, actual) { 64 | return actual < expected; 65 | }, 66 | 67 | failure_message: function(expected, actual, not) { 68 | return 'expected ' + $.print(actual) + (not ? ' to not ' : ' to ') + 'be less than ' + $.print(expected); 69 | } 70 | }, 71 | 72 | be_lte: { 73 | match: function(expected, actual) { 74 | return actual <= expected; 75 | }, 76 | 77 | failure_message: function(expected, actual, not) { 78 | return 'expected ' + $.print(actual) + (not ? ' to not ' : ' to ') + 'be less than or equal to ' + $.print(expected); 79 | } 80 | }, 81 | 82 | match: { 83 | match: function(expected, actual) { 84 | if (expected.constructor == RegExp) 85 | return expected.exec(actual.toString()); 86 | else 87 | return actual.indexOf(expected) > -1; 88 | }, 89 | 90 | failure_message: function(expected, actual, not) { 91 | return 'expected ' + $.print(actual) + (not ? ' to not match ' : ' to match ') + $.print(expected); 92 | } 93 | }, 94 | 95 | be_empty: { 96 | match: function(expected, actual) { 97 | if (actual.length == undefined) throw(actual.toString() + " does not respond to length"); 98 | 99 | return actual.length == 0; 100 | }, 101 | 102 | failure_message: function(expected, actual, not) { 103 | return 'expected ' + $.print(actual) + (not ? ' to not be empty' : ' to be empty'); 104 | } 105 | }, 106 | 107 | have_length: { 108 | match: function(expected, actual) { 109 | if (actual.length == undefined) throw(actual.toString() + " does not respond to length"); 110 | 111 | return actual.length == expected; 112 | }, 113 | 114 | failure_message: function(expected, actual, not) { 115 | return 'expected ' + $.print(actual) + (not ? ' to not' : ' to') + ' have length ' + expected; 116 | } 117 | }, 118 | 119 | be_null: { 120 | match: function(expected, actual) { 121 | return actual == null; 122 | }, 123 | 124 | failure_message: function(expected, actual, not) { 125 | return 'expected ' + $.print(actual) + (not ? ' to not be null' : ' to be null'); 126 | } 127 | }, 128 | 129 | be_undefined: { 130 | match: function(expected, actual) { 131 | return actual == undefined; 132 | }, 133 | 134 | failure_message: function(expected, actual, not) { 135 | return 'expected ' + $.print(actual) + (not ? ' to not be undefined' : ' to be undefined'); 136 | } 137 | }, 138 | 139 | be_true: { 140 | match: function(expected, actual) { 141 | return actual; 142 | }, 143 | 144 | failure_message: function(expected, actual, not) { 145 | return 'expected ' + $.print(actual) + (not ? ' to not be true' : ' to be true'); 146 | } 147 | }, 148 | 149 | be_false: { 150 | match: function(expected, actual) { 151 | return !actual; 152 | }, 153 | 154 | failure_message: function(expected, actual, not) { 155 | return 'expected ' + $.print(actual) + (not ? ' to not be false' : ' to be false'); 156 | } 157 | }, 158 | 159 | match_selector: { 160 | match: function(expected, actual) { 161 | if (!(actual instanceof jQuery)) { 162 | throw expected.toString() + " must be an instance of jQuery to match against a selector" 163 | } 164 | 165 | return actual.is(expected); 166 | }, 167 | 168 | failure_message: function(expected, actual, not) { 169 | return 'expected ' + $.print(actual) + (not ? ' to not match selector ' : ' to match selector ') + expected; 170 | } 171 | }, 172 | 173 | contain_selector: { 174 | match: function(expected, actual) { 175 | if (!(actual instanceof jQuery)) { 176 | throw expected.toString() + " must be an instance of jQuery to match against a selector" 177 | } 178 | 179 | return actual.find(expected).length > 0; 180 | }, 181 | 182 | failure_message: function(expected, actual, not) { 183 | return 'expected ' + $.print(actual) + (not ? ' to not contain selector ' : ' to contain selector ') + expected; 184 | } 185 | } 186 | } 187 | })(jQuery); -------------------------------------------------------------------------------- /src/com/karura/framework/ui/webview/KaruraWebViewClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | This file derived from Cordova Android Project available under the Apache 2.0 License 3 | Please refer to APACHE-LICENCE2.0.txt for attributions 4 | */ 5 | 6 | /** 7 | 8 | ============== GPL License ============== 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | 22 | 23 | ============== Commercial License============== 24 | https://github.com/karuradev/licenses/blob/master/toc.txt 25 | */ 26 | 27 | 28 | package com.karura.framework.ui.webview; 29 | 30 | import java.io.IOException; 31 | import java.io.InputStream; 32 | 33 | import android.annotation.SuppressLint; 34 | import android.content.ActivityNotFoundException; 35 | import android.content.Context; 36 | import android.content.Intent; 37 | import android.graphics.Bitmap; 38 | import android.net.Uri; 39 | import android.util.Log; 40 | import android.webkit.MimeTypeMap; 41 | import android.webkit.WebResourceResponse; 42 | import android.webkit.WebView; 43 | import android.webkit.WebViewClient; 44 | 45 | import com.karura.framework.KaruraApp; 46 | import com.karura.framework.Constants; 47 | import com.karura.framework.config.ConfigStore; 48 | 49 | public class KaruraWebViewClient extends WebViewClient implements Constants { 50 | static final String TAG = "KaruraWebViewClient"; 51 | private KaruraWebView webView; 52 | 53 | public KaruraWebViewClient(KaruraWebView webViewEx) { 54 | webView = webViewEx; 55 | } 56 | 57 | public KaruraApp getApp() { 58 | return KaruraApp.getApp(); 59 | } 60 | 61 | public ConfigStore appConfig() { 62 | return getApp().getAppConfig(); 63 | } 64 | 65 | 66 | /** 67 | * Notify the host application of a resource request and allow the application to return the data. If the return 68 | * value is null, the WebView will continue to load the resource as usual. Otherwise, the return response and data 69 | * will be used. 70 | */ 71 | 72 | @SuppressLint("NewApi") 73 | @Override 74 | public WebResourceResponse shouldInterceptRequest(WebView webView, String url) { 75 | KaruraWebView webViewEx = (KaruraWebView) webView; 76 | if (webViewEx.disallowFileAccess && url.startsWith("file://")) { 77 | Log.e(TAG, "url: " + url); 78 | return new WebResourceResponse(null, null, null); 79 | } 80 | 81 | if (url.startsWith("data:image/png;base64")) { 82 | return super.shouldInterceptRequest(webView, url); 83 | } 84 | 85 | String fileExt = MimeTypeMap.getFileExtensionFromUrl(url); 86 | String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt); 87 | 88 | String path = null; 89 | if (url.startsWith("file:///android_asset/")){ 90 | path = url.substring("file:///android_asset/".length(), url.length()); 91 | }else if (url.startsWith("file:///")){ 92 | path = url.substring("file:///".length(), url.length()); 93 | } 94 | if (path != null) { 95 | WebResourceResponse result = getWebResourceResponseFromAsset(webView.getContext(), path, mimeType); 96 | if (result != null) { 97 | return result; 98 | } 99 | } 100 | 101 | return super.shouldInterceptRequest(webView, url); 102 | } 103 | 104 | @SuppressLint("NewApi") 105 | public WebResourceResponse getWebResourceResponseFromAsset(Context context, String path, String mimeType) { 106 | InputStream is = null; 107 | try { 108 | is = context.getAssets().open(path); 109 | return new WebResourceResponse(mimeType, "UTF-8", is); 110 | } catch (IOException e) { 111 | Log.e(TAG, e.toString()); 112 | } 113 | return null; 114 | } 115 | 116 | /** 117 | * Notify the host application of a resource request and allow the application to return the data. If the return 118 | * value is null, the WebView will continue to load the resource as usual. Otherwise, the return response and data 119 | * will be used. 120 | */ 121 | 122 | @Override 123 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 124 | Log.e(TAG, "shouldOverrideUrlLoading(): " + Uri.parse(url).getHost()); 125 | 126 | if (url.startsWith(WebView.SCHEME_TEL)) { 127 | try { 128 | Intent intent = new Intent(Intent.ACTION_DIAL); 129 | intent.setData(Uri.parse(url)); 130 | webView.getActivity().startActivity(intent); 131 | } catch (android.content.ActivityNotFoundException e) { 132 | Log.e(TAG, "Error handling Tel URL -> " + url + ": " + e.toString()); 133 | } 134 | } else if (url.startsWith("geo:")) { 135 | try { 136 | Intent intent = new Intent(Intent.ACTION_VIEW); 137 | intent.setData(Uri.parse(url)); 138 | webView.getActivity().startActivity(intent); 139 | } catch (ActivityNotFoundException e) { 140 | Log.e(TAG, "Error loading maps -> " + url + ": " + e.toString()); 141 | } 142 | } else if (url.startsWith(WebView.SCHEME_MAILTO)) { 143 | try { 144 | Intent intent = new Intent(Intent.ACTION_VIEW); 145 | intent.setData(Uri.parse(url)); 146 | webView.getActivity().startActivity(intent); 147 | } catch (ActivityNotFoundException e) { 148 | Log.e(TAG, "Error opening email composer -> " + url + ": " + e.toString()); 149 | } 150 | } else if (url.startsWith("sms:")) { 151 | try { 152 | Intent intent = new Intent(Intent.ACTION_VIEW); 153 | 154 | String address = null; 155 | int parmIndex = url.indexOf('?'); 156 | if (parmIndex == -1) { 157 | address = url.substring(4); 158 | } else { 159 | address = url.substring(4, parmIndex); 160 | 161 | Uri uri = Uri.parse(url); 162 | String query = uri.getQuery(); 163 | if (query != null) { 164 | if (query.startsWith("body=")) { 165 | intent.putExtra("sms_body", query.substring(5)); 166 | } 167 | } 168 | } 169 | intent.setData(Uri.parse("sms:" + address)); 170 | intent.putExtra("address", address); 171 | intent.setType("vnd.android-dir/mms-sms"); 172 | webView.getActivity().startActivity(intent); 173 | } catch (android.content.ActivityNotFoundException e) { 174 | Log.e(TAG, "Error sending sms " + url + ":" + e.toString()); 175 | } 176 | } 177 | 178 | else { 179 | if (url.startsWith("file://") || url.indexOf(webView.baseUrl) == 0 || webView.isUrlWhiteListed(url)) { 180 | webView.loadUrl(url); 181 | } 182 | 183 | else { 184 | try { 185 | Intent intent = new Intent(Intent.ACTION_VIEW); 186 | intent.setData(Uri.parse(url)); 187 | webView.getActivity().startActivity(intent); 188 | } catch (android.content.ActivityNotFoundException e) { 189 | Log.e(TAG, "Error loading url " + url, e); 190 | } 191 | } 192 | } 193 | 194 | return true; 195 | } 196 | 197 | @Override 198 | public void onPageStarted(WebView view, String url, Bitmap favicon) { 199 | Log.e(TAG, "onPageStarted()"); 200 | super.onPageStarted(view, url, favicon); 201 | } 202 | 203 | @Override 204 | public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { 205 | Log.e(TAG, "error: " + description + " \n errorCode: " + errorCode + "\n failingUrl: " + failingUrl); 206 | } 207 | } --------------------------------------------------------------------------------