# RunJavaScript
> Build, integrate and automate using JavaScript on IOS.
This application provides a JavaScript development environment directly on your IOS device. You can build, integrate and automate using **RunJavaScript**, it is a powerful companion if you integrate it with other apps using the URL scheme. Utilising the [x-callback-url][x-callback-url-website] specification, you can add JavaScript steps into your workflows using other apps like [Apple Shortcuts][shortcuts-website], [Launch Center Pro][launch-center-website], etc.
[x-callback-url-website]: http://x-callback-url.com/
[shortcuts-website]: https://support.apple.com/en-gb/guide/shortcuts/welcome/ios
[launch-center-website]: https://contrast.co/launch-center-pro/
### Features
* Run using Shorcuts action, [click for sample workflow](https://www.icloud.com/shortcuts/a0b68a745ec6447ca2059a6e5c71b78a)
* x-callback-url integration
* Add scripts to home screen
* Editor to create script URL
* Execute JavaScript files stored in App documents
* WebDAV server to access the script files. You can use your favourite editor to edit the JavaScript files.
### URL Scheme
RunJavaScript registers the `runjavascript://` URL scheme and supports `x-callback-url` protocol.
The URL syntax is like this:
```
runjavascript://x-callback-url/run?script=[js-script]&code=[security code]&file=[file path]&input=[input]&baseURL=...&x-success=...&x-error=...
```
Following URL parameters can be provided:
* `script` URL encoded JavaScript to run.
* `code` (optional) Security code for the script. It should match the code configured in settings otherwise script will open in editor mode with an alert.
* `file` is used to execute JavaScript files stored in the local documents folder or at a remote location. Files ending with _.js_ will be handled as script file. Files ending with _.html_ will be rendered as web page and RunJavaScript API will be injected. Any http resource will be rendered as web page and RunJavaScript API will be injected. `script` parameter can be used at the same time and given script will be executed after the file. Either `script` or `file` parameter is required. Examples:
* `file=test.js`
* `file=test.html`
* `file=https://some.domain.com/path`
* `baseURL`(optional) value will be set as the origin of execution environment. It is useful while making REST calls to remote servers.
* `input`(optional) input data to be used by the script. Input can be text (URL encoded), JSON (URL encoded) or other format.
* `x-success`(optional) A URL to open when execution is successful.
* `x-error`(optional) A URL that will be called if the given script has an error.
* `inputName`(optional) Parameter name used as input. If provided input data will be retrieved from parameter named by `inputName`.
### RunJavaScript API
RunJavaScript provides some functions to be used by custom scripts. You can shake the device while running the script to display a developer menu. Enable *Always Open in Editor* setting to view the code without executing.
#### Functions of `runjs`:
* `runjs.getInput().text()` returns input as text. [Click to run sample][runjs_getinput_text].
* `runjs.getInput().json()` returns input as JSON. [Click to run sample][runjs_getinput_json].
* `runjs.print(out)` prints given parameter as string on screen. [Click to run sample][runjs_print].
* `runjs.printHTML(out)` displays given HTML on screen. HTML will be rendered. You can even add buttons. [Click to run sample][runjs_print_html].
* `runjs.callback(value)` Calls x-success URL by adding the value as `input` parameter (URL encoded). If x-success parameter is not set `close()` will be called.
* `runjs.callback()` Calls x-success URL without result. If x-success parameter is not set `close()` will be called.
* `runjs.close()` returns to the home screen of RunJavaScript app.
* `runjs.redirect(url)` redirects the page to given url.
* `runjs.openInSafari(url)` opens given url in Safari.
* `runjs.importScript(url)` loads given script. URL can be local(relative) or remote.
* `runjs.importCSS(url)` loads given CSS. URL can be local(relative) or remote.
* `runjs.addScript(script)` loads given script text. [Click to view a complex sample][runjs_addScript].
* `runjs.addStyle(css)` loads given CSS text.
* `runjs.setIdleTimerState(bool)` sets IOS idle timer state. Set to _false_ to disable screen lock. [Click to run sample][runjs_setIdleTimerState].
* `runjs.openXCallbackURL(url, inputName)` performs x-callback-url action using the given `url` parameter and returns a promise. x-success and x-error parameters will be populated automatically. Thanks to the promise this method can be used to call other apps, get some response and continue the execution flow. `inputName` is optional and can be used to map the response parameter name of the called app. See [battery meter][battery_meter_sample] sample.
[runjs_getinput_text]: runjavascript://x-callback-url/run?script=alert(runjs.getInput().text())%0A%20%20.then(function()%7Brunjs.close()%7D)&input=Hello%20World
[runjs_getinput_json]: runjavascript://x-callback-url/run?script=alert(runjs.getInput().json().text)%0A%20%20.then(function()%7Brunjs.close()%7D)&input=%7B%22text%22%3A%20%22Hello%20World%22%7D
[runjs_print]: runjavascript://x-callback-url/run?script=runjs.print(%22Hello%20World!%20Use%20the%20X%20below%20to%20close.%22)%3B
[runjs_print_HTML]: runjavascript://x-callback-url/run?script=runjs.printHTML(%22%3CH1%3EHello%20World!%3C/H1%3EUse%20the%20X%20below%20to%20close.%22)%3B
[runjs_setIdleTimerState]: runjavascript://x-callback-url/run?script=runjs.printHTML(%22%3Cstrong%3EScreen%20lock%20disabled!%3C/strong%3E%20Use%20the%20X%20below%20to%20close.%22)%3B%0Arunjs.setIdleTimerState(false)%3B
[runjs_addScript]: runjavascript://edit?script=(async()%20=%3E%20%7B%0A%20%20%20%20var%20gistURL%20=%20'https://gist.githubusercontent.com/ekinsokmen/24d3181f1bd6c7c98fa5b1fbf46835e9/raw/RunJavaScript%252520Hello%252520World'%3B%0A%20%20%20%20var%20fetchPromise%20=%20await%20fetch(gistURL)%3B%0A%20%20%20%20var%20script%20=%20await%20fetchPromise.text()%3B%0A%20%20%20%20runjs.addScript(script)%3B%0A%7D)().catch(err%20=%3E%20console.log(err))%3B&baseURL=https%3A//gist.githubusercontent.com
[battery_meter_sample]: https://github.com/ekinsokmen/runjavascript-gallery/tree/master/how-to/integration/workflow/battery-meter
#### Clipboard
* `Clipboard.getString()` return IOS clipboard value as text. Function returns a promise.
* `Clipboard.setString(value)` sets given text value to IOS clipboard.
* [Sample][clipboard_01]
[clipboard_01]: runjavascript://x-callback-url/run?script=(async%20function()%7B%0A%20%20await%20Clipboard.setString(%22Hello%20World!%22)%3B%0A%20%20var%20cbValue%20=%20await%20Clipboard.getString()%3B%0A%20%20await%20alert(%22Clipboard%20value%3A%20%22%20%2B%20cbValue)%3B%0A%20%20runjs.close()%3B%0A%7D)()%0A%0A
#### Alert
* `Alert.alert(title, message?, buttons?)` displays native alert box. The usage is based on [React Native Alert API][alert_doc]. Plain JavaScript *alert* function is also mapped to native alert API. In addition to React Native and plain alert syntax, this function returns a promise. The clicked button name will be the value of resolved promise.
* [Sample 1][alert_01]
* [Sample 2][alert_02]
* [Sample 3][alert_03]
[alert_doc]: https://facebook.github.io/react-native/docs/alert.html
[alert_01]: runjavascript://x-callback-url/run?script=Alert.alert('Hello'%2C%20'Universe!').then(%0A%20%20function(b)%20%7B%0A%20%20%20%20runjs.close()%3B%0A%20%20%7D%0A)
[alert_02]: runjavascript://x-callback-url/run?script=Alert.alert('Hello'%2C%20'Universe!'%2C%0A%5B%0A%20%20%7Btext%3A%20%22Ok%22%2C%20onPress%3A%20function()%7Brunjs.print(%22Use%20the%20X%20below%20to%20close.%22)%7D%7D%2C%0A%20%20%7Btext%3A%20%22Close%22%2C%20onPress%3A%20function()%7Brunjs.close()%7D%7D%0A%5D%20%20%20%20%20%20%20%20%20%20%20%0A)%0A
[alert_03]: runjavascript://x-callback-url/run?script=alert('Hello%20World').then(%0A%20%20function(b)%20%7B%0A%20%20%20%20runjs.close()%3B%0A%20%20%7D%0A)
#### Location
* `navigator.geolocation.getCurrentPosition(success?, error?, [options]?)` returns current location using native API. Usage is similar to plain javascript function (see [MSN getCurrentPosition][location_doc]). Supported options are enableHighAccuracy(bool), locationAccuracyInMeters(integer), timeout(integer). The function returns a promise. The location object will be passed to resolved promise.
* [Sample 1][location_01]
* [Sample 2][location_02]
[location_doc]: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition
[location_01]: runjavascript://x-callback-url/run?script=navigator.geolocation.getCurrentPosition(%0A%20%20function(l)%20%7Brunjs.print(JSON.stringify(l.coords))%7D%2C%0A%20%20function(err)%20%7Balert(%22Error%3A%20%22%20%2B%20err.message)%7D%2C%0A%20%20%7Btimeout%3A%203000%7D%0A)
[location_02]: runjavascript://x-callback-url/run?script=navigator.geolocation.getCurrentPosition()%0A%20%20.then(function(l)%7B%0A%20%20%09runjs.print(JSON.stringify(l.coords))%0A%7D)
### ⚠️ Security and Privacy
* ⚠️ DO NOT ENTER YOUR PASSWORD, other authentication information or any other sensitive data, unless YOU KNOW WHAT YOU ARE DOING
* ⚠️ You should review all scripts from unknown/untrusted sources with extra caution to confirm that they function as you expect
* ⚠️ RunJavaScript app and the developer have no control over, and assume no responsibility for, the content or functionality of third-party scripts
* ℹ️ RunJavaScript provides support to prevent unknown scripts to run by setting an optional security code. You can enable the security code in the settings tab and pass it as `code` parameter.
* ✅ by using this RunJavaScript app you acknowledge that you have read, understood and agree on the risks and responsibility
### Online Resources:
* [RunJavaScript Sample Gallery][runjsgallery]
* [How To Videos][howtovideos]
* [RunJavaScript Web Site][runjsweb]
[runjsweb]: http://www.runjavascriptapp.com
[runjsgallery]: https://github.com/ekinsokmen/runjavascript-gallery
[howtovideos]: https://www.youtube.com/playlist?list=PLQSz6uzgEjvQt_N08tyJtumdca2EHoTj3
---
### Contact
[![Ekin Sokmen][linkedInImg]][linkedInURL]
[linkedInURL]: http://www.linkedin.com/in/ekin-sokmen
[linkedInImg]: http://www.runjavascriptapp.com/in-logo.png "Contact the developer"