├── JSPluginGen ├── Documentation.html ├── JSPluginGen.js ├── Plugin.js └── res │ ├── PluginTest.js │ └── config.json └── README.md /JSPluginGen/Documentation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | MyPlugin 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | Back 15 |

MyJSPlugin

16 |
17 | 18 |
19 | 20 |

In order to use MyJSPlugin, you must first load the plugin at the top of your script 21 | using the LoadPlugin method like this:

22 | 23 |
 app.LoadPlugin( "MyJSPlugin" );
24 | 25 |

Then you can create an instance of the plugin object when you need it like this:

26 | 27 |
 plg = app.CreateMyJSPlugin();
28 | 29 |
30 |

Examples:

31 | 32 |
33 |

Example - Get Version

34 |
35 | app.LoadPlugin( "MyJSPlugin" );
36 |
37 | function OnStart()
38 | {
39 |     lay = app.CreateLayout( "Linear", "VCenter,FillXY" );

40 |     btn = app.CreateButton( "Get Plugin Version" );
41 |     btn.SetOnTouch( CallPlugin );
42 |     lay.AddChild( btn );

43 | 44 |     plg = app.CreateMyJSPlugin();
45 |

46 |     app.AddLayout( lay );
47 | }
48 |
49 | function CallPlugin()
50 | {
51 |     alert( plg.GetVersion() );
52 | }

53 |
54 |
55 |   Copy   56 | Copy All 57 |    Run    58 |
59 |
60 |
61 |
62 | 63 | 64 | -------------------------------------------------------------------------------- /JSPluginGen/JSPluginGen.js: -------------------------------------------------------------------------------- 1 | 2 | (function(){ 3 | 4 | var touch = true; //when false it disables the back button 5 | var showAlert = true; //show initial alert info message 6 | var appPath = app.GetAppPath(); //get public directory 7 | var configPath = appPath + "/res/configPath.json"; //save configPath 8 | var conf = {name: "", assets: "Html,Img,Snd", exec: false}; 9 | var _exit; 10 | 11 | LoadConf(); 12 | 13 | if(conf.exec) { 14 | saveConf("exec", false); 15 | app.LoadScript(appPath + "/res/~PluginTest.js"); 16 | return; 17 | } 18 | 19 | OnStart = function() { _OnStart(); }; 20 | OnBack = function() { _OnBack(); }; 21 | 22 | function _OnStart() { 23 | 24 | //show info message 25 | if(showAlert) app.Alert("This is just the plugin installer\n\nPlugin.js is your plugin file which you should edit.\n\nDocumentation.html contains the documentation of your plugin.\n\nYou will have to run this app to be sure all files are saved\n\nYou should only execute this app in DroidScript itself. It is not supposed to work as apk.\n\nHappy Coding!\n\nbest regards,\nSymbroson", "Information"); 26 | 27 | //disable back key and lock orientation 28 | app.EnableBackKey(false); 29 | app.SetOrientation( app.GetOrientation() ); 30 | 31 | //GUI 32 | layMain = app.CreateLayout("absolute"); 33 | 34 | var scrLay = app.CreateScroller(1, 1); 35 | layMain.AddChild(scrLay); 36 | 37 | var lay = app.CreateLayout("Linear"); 38 | scrLay.AddChild(lay); 39 | lay.SetSize(1, 1); 40 | 41 | var txtTitle = app.CreateText("JavaScript Plugin
installer for DS
", -1, -1, "html,multiline"); 42 | txtTitle.SetTextSize(30, "dip"); 43 | txtTitle.SetMargins(0, .03); 44 | lay.AddChild(txtTitle); 45 | 46 | txtName = app.CreateText(conf.name, .8, -1, "center"); 47 | txtName.SetTextSize(25, "dip"); 48 | txtName.SetMargins(0, .05); 49 | lay.AddChild(txtName); 50 | 51 | var txtAssets = app.CreateText("Additional ressources
comma separated list of files or folders which will be included to the plugin", .8, -1, "html,multiline,left"); 52 | txtAssets.SetMargins(0, .035, 0, .02); 53 | txtAssets.SetTextSize(15, "dip"); 54 | lay.AddChild(txtAssets); 55 | 56 | edtAssets = app.CreateTextEdit(conf.assets, .8, -1, "singleline"); 57 | edtAssets.SetOnChange(edtAssets_OnChange); 58 | edtAssets.SetTextSize(17, "dip"); 59 | edtAssets.name = "assets"; 60 | lay.AddChild(edtAssets); 61 | 62 | var btnZip = app.CreateButton("Export Plugin Zip", .7); 63 | btnZip.SetOnTouch(btnZip_OnTouch); 64 | btnZip.SetMargins(0, .04); 65 | lay.AddChild(btnZip); 66 | 67 | var btnInstall = app.CreateButton("Install Plugin (instant)", .7); 68 | btnInstall.SetEnabled(appPath === "/sdcard/DroidScript/" + app.GetAppName()); 69 | btnInstall.SetOnTouch(btnInstall_OnTouch); 70 | lay.AddChild(btnInstall); 71 | 72 | var btnUninstall = app.CreateButton("Uninstall Plugin", .7); 73 | btnUninstall.SetOnTouch(btnUninstall_OnTouch); 74 | lay.AddChild(btnUninstall); 75 | 76 | var btnTest = app.CreateButton("Test plugin ->", .7); 77 | btnTest.SetOnTouch(btnTest_OnTouch); 78 | lay.AddChild(btnTest); 79 | 80 | layTest = app.CreateLayout("absolute", "fillxy,VCenter"); 81 | layTest.SetBackColor("#ee000000"); 82 | layTest.SetVisibility("Hide"); 83 | layTest.SetSize(1, 1); 84 | 85 | if(false && app.IsPremium()) { //use code edit 86 | edtCode = app.CreateCodeEdit("", 1, .9, ""); 87 | edtCode.SetColorScheme("dark"); 88 | edtCode.SetBackColor("#00000000"); 89 | layTest.AddChild(edtCode); 90 | } else { //use horizontal scroller with text edit 91 | var scr = app.CreateScroller(1, .9); 92 | var layScr = app.CreateLayout("linear"); 93 | layScr.SetSize(10, .9); 94 | edtCode = app.CreateTextEdit("", 10, .9, "monospace"); 95 | layScr.AddChild(edtCode); 96 | scr.AddChild(layScr); 97 | layTest.AddChild(scr); 98 | } 99 | 100 | edtCode.SetOnChange(edtCode_OnChange); 101 | edtCode.SetTextSize(14, "dip"); 102 | edtCode.name = "code"; 103 | 104 | var btnBack = app.CreateButton("Back", .2); 105 | btnBack.SetOnTouch(btnBack_OnTouch); 106 | btnBack.SetPosition(.05, .9); 107 | layTest.AddChild(btnBack); 108 | 109 | var btnUndo = app.CreateButton("Undo", .2); 110 | btnUndo.SetOnTouch(edtCode.Undo); 111 | btnUndo.SetPosition(.275, .9); 112 | layTest.AddChild(btnUndo); 113 | 114 | var btnRedo = app.CreateButton("Redo", .2); 115 | btnRedo.SetOnTouch(edtCode.Redo); 116 | btnRedo.SetPosition(.5, .9); 117 | layTest.AddChild(btnRedo); 118 | 119 | var btnRun = app.CreateButton("Run", .2); 120 | btnRun.SetOnTouch(btnRun_OnTouch); 121 | btnRun.SetPosition(.725, .9); 122 | layTest.AddChild(btnRun); 123 | 124 | layMain.AddChild(layTest); 125 | 126 | app.AddLayout(layMain); 127 | 128 | if(!conf.name) { 129 | do 130 | conf.name = prompt("How would you like your plugin to be called?", ""); 131 | while(!conf.name || !conf.name.trim()); 132 | 133 | alert("Your plugin will be called '" + conf.name + "'.\n\nIf your ok with that" + 134 | " press Ok.\nIf not, exit the app immediately.\n\nAfterwards you have to" + 135 | " modify Plugin.js and Documentation.html file in order to change the name."); 136 | 137 | saveConf("name", conf.name.trim()); 138 | txtName.SetText(conf.name); 139 | app.ReplaceInFile(appPath + "/Plugin.js", "%PLGNAME%", conf.name); 140 | app.ReplaceInFile(appPath + "/Documentation.html", "%PLGNAME%", conf.name); 141 | app.ReplaceInFile(appPath + "/res/PluginTest.js", "%PLGNAME%", conf.name); 142 | } 143 | 144 | edtCode.SetText(app.ReadFile(appPath + "/res/PluginTest.js")); 145 | } 146 | 147 | //Export plugin zip to public folder 148 | function btnZip_OnTouch() { 149 | app.ShowProgress("Zipping"); 150 | 151 | //get zip destination and delete file if it exists 152 | var path = appPath + "/" + conf.name + ".zip"; 153 | if(app.FileExists(path)) app.DeleteFile(path); 154 | 155 | //zipping process 156 | var zip = app.CreateZipUtil(); 157 | zip.Create(path); 158 | 159 | //add and rename Plugin.js and Documentation.html to .inc and .html 160 | zip.AddFile(appPath + "/" + conf.name + ".inc", appPath + "/Plugin.js"); 161 | zip.AddFile(appPath + "/" + conf.name + ".html", appPath + "/Documentation.html"); 162 | 163 | //append additional assets 164 | var lst = edtAssets.GetText().split(","); 165 | for(var i in lst) { 166 | var file = lst[i]; 167 | if(!lst[i].startsWith("/")) file = appPath + "/" + file; 168 | if(app.FolderExists(file) || app.FileExists(file)) 169 | AddToZip(zip, path, file); 170 | } 171 | 172 | zip.Close(); 173 | 174 | app.HideProgress(); 175 | app.ShowPopup("Zip created at " + path); 176 | } 177 | 178 | //add items to zip file 179 | function AddToZip(zip, name, path) { 180 | if(app.IsFolder(path)) { 181 | var lst = app.ListFolder(path, ""); 182 | for(var i = 0; i < list.length; i++) addToZip(zip, name + "/" + path, path + "/" + lst[i]) 183 | } else zip.AddFile(name + "/" + path, path); 184 | } 185 | 186 | //instant install plugin 187 | function btnInstall_OnTouch() { 188 | 189 | app.ShowProgress("Installing"); 190 | 191 | //get name and define destination directories 192 | var privdir = app.GetPrivateFolder("Plugins"); // appPath + "/../Plugins"; 193 | var paths = [privdir, appPath + "/../.edit/docs/plugins"]; 194 | 195 | //copy plugin files to each destination 196 | paths.forEach( function(path) { 197 | //create lower-cased folder 198 | path += "/" + conf.name.toLowerCase() + "/"; 199 | if(!app.FolderExists(conf.name)) app.MakeFolder(path); 200 | 201 | //copy and rename Plugin.js and Documentation.html to .inc and .html 202 | app.CopyFile(appPath + "/Plugin.js", path + conf.name + ".inc"); 203 | app.CopyFile(appPath + "/Documentation.html", path + conf.name + ".html"); 204 | 205 | //copy additional assets 206 | var lst = edtAssets.GetText().split(","); 207 | for(var i in lst) { 208 | if(app.FolderExists(lst[i])) app.CopyFolder(lst[i], path + lst[i], true); 209 | else if(app.FileExists(lst[i])) { 210 | var fld = path + lst[i]; 211 | fld = fld.slice(0, fld.lastIndexOf("/")); 212 | if(!app.FolderExists(fld)) app.MakeFolder(fld); 213 | app.CopyFile(lst[i], path + lst[i]); 214 | } 215 | } 216 | } ); 217 | 218 | app.HideProgress(); 219 | app.ShowPopup("Plugin '" + conf.name + "' installed!"); 220 | } 221 | 222 | //instant uninslall 223 | function btnUninstall_OnTouch() { 224 | app.ShowProgress("Uninstalling"); 225 | 226 | //delete private dir 227 | var path = app.GetPrivateFolder("Plugins") + "/" + conf.name.toLowerCase(); 228 | if(app.FolderExists(path)) app.DeleteFolder(path); 229 | 230 | //delete public dir 231 | path = appPath + "/../.edit/docs/plugins/" + conf.name.toLowerCase(); 232 | if(app.FolderExists(path)) app.DeleteFolder(path); 233 | 234 | app.HideProgress(); 235 | app.ShowPopup("Plugin '" + conf.name + "' deistalled!\nRestart DroidScript to see the effect"); 236 | } 237 | 238 | //show test area 239 | function btnTest_OnTouch() { 240 | layMain.SetTouchable(touch = false); 241 | layTest.Animate("SlideFromRight", function() { layMain.SetTouchable(touch = true); }); 242 | } 243 | 244 | //hide test area 245 | function btnBack_OnTouch() { 246 | layMain.SetTouchable(touch = false); 247 | layTest.Animate("SlideToRight", function() { layMain.SetTouchable(touch = true); }); 248 | } 249 | 250 | //run code from text area 251 | function btnRun_OnTouch() { 252 | //execute test code 253 | var code = edtCode.GetText(); 254 | app.WriteFile(appPath + "/res/PluginTest.js", code); 255 | app.WriteFile(appPath + "/res/~PluginTest.js", code.replace(/%PLGNAME%/g, conf.name)); 256 | if(app.IsAPK()) app.StartApp(appPath + "/res/~PluginTest.js"); 257 | else { 258 | saveConf("exec", true); 259 | app.SetAlarm("Set", 2542, null, Date.now()+1000); 260 | app.Exit(); 261 | } 262 | } 263 | 264 | //save test code 265 | function edtCode_OnChange() { 266 | if(edtCode.tmt) clearTimeout(edtCode.tmt); 267 | edtCode.tmt = setTimeout( function() { 268 | app.WriteFile(appPath + "/PluginTest.js", edtCode.GetText().replace(/\xa0/g, " ")); 269 | edtCode.tmt = false; 270 | }, 5000 ); 271 | } 272 | 273 | //onchange-save method for text edits 274 | //saves data after one second no input 275 | function edtAssets_OnChange() { 276 | var obj = this; 277 | if(obj.tmt) clearTimeout(obj.tmt); 278 | obj.tmt = setTimeout( function() { 279 | saveConf("assets", obj.GetText()); 280 | obj.tmt = false; 281 | }, 1000 ); 282 | } 283 | 284 | //save text across multiple starts 285 | function saveConf(key, val) { 286 | if(key) conf[key] = val; 287 | app.WriteFile(configPath, JSON.stringify(conf)); 288 | } 289 | 290 | function LoadConf() { 291 | try { 292 | obj = JSON.parse(app.ReadFile(configPath) || "{}"); 293 | } catch(e){ 294 | app.ShowPopup("corrupt config file. Resetting."); 295 | } 296 | for(var i in obj) conf[i] = obj[i]; 297 | saveConf(); 298 | } 299 | 300 | //handle back-key event 301 | function _OnBack() { 302 | if(!touch) return; //back key locked 303 | 304 | //hide test area if visible 305 | if(layTest.IsVisible()) return btnBack_OnTouch(); 306 | 307 | //exit app after second press 308 | if(_exit) app.Exit(); 309 | else app.ShowPopup("press back again to exit"); 310 | 311 | //set timeout to exit app 312 | _exit = true; 313 | setTimeout("_exit=false", 2000); 314 | } 315 | 316 | })(); 317 | -------------------------------------------------------------------------------- /JSPluginGen/Plugin.js: -------------------------------------------------------------------------------- 1 | 2 | //returns new plugin instance 3 | app.Create%PLGNAME% = function() { 4 | return new _%PLGNAME%(); 5 | } 6 | 7 | //should contain EVERY function 8 | //it is recommended to don't place other functions outside this class 9 | //and also don't define public variables to prevent difficulties 10 | //when the user already uses them (so they won't be overridden) 11 | function _%PLGNAME%() { 12 | this.GetVersion = function() { return "1.00" }; 13 | } 14 | -------------------------------------------------------------------------------- /JSPluginGen/res/PluginTest.js: -------------------------------------------------------------------------------- 1 | 2 | app.LoadPlugin("%PLGNAME%"); 3 | 4 | function OnStart() { 5 | plg = app.Create%PLGNAME%(); 6 | 7 | var lay = app.CreateLayout("Linear", "VCenter,FillXY"); 8 | btn = app.CreateButton("GetVersion"); 9 | btn.SetOnTouch(CallPlugin); 10 | lay.AddChild(btn); 11 | app.AddLayout(lay); 12 | } 13 | 14 | function CallPlugin() { 15 | alert(plg.GetVersion()); 16 | } 17 | -------------------------------------------------------------------------------- /JSPluginGen/res/config.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DroidScript-JS-Plugin-Generator 2 | A JavaScript Plugin generator for DroidScript 3 | 4 | Just copy the JSPluginGen folder to the DroidScript projects folder (/sdcard/DroidScript/) and (re)start DroidScript, or install the spk available here: https://dspk.justplayer.de/browse/view/67 5 | 6 | This template provides an instant plugin installer, deinstaller and exporter, as well as a quick plugin test area. 7 | 8 | You may (and should) rename the DroidScript project according to your wishes. 9 | However you shouldn't modify the main JSPluginGen.js script. 10 | 11 | The Plugin.js and the Documentation.html file contain the source of your documentation. 12 | 13 | Happy coding 14 | 15 | 16 | Files 17 | ----- 18 | ```c 19 | - JSPluginGen.js       template which can install, deinstall and export the Plugin 20 | - Plugin.js includes the plugin sources 21 | - Documentation.html the documentation template of all DroidScript plugins 22 | ``` 23 | 24 | 25 | DroidScript: 26 | - [Website](http://droidscript.org/) 27 | - [GooglePlay](https://play.google.com/store/apps/details?id=com.smartphoneremote.androidscriptfree) 28 | - [Forum](https://groups.google.com/forum/#!forum/androidscript) 29 | --------------------------------------------------------------------------------