Userscripts dev
- - - -- This is the development preview environment -
-
-10. **Open Page Link** - *macOS only*, opens the extension browser page
+10. **Open Page Link** - _macOS only_, opens the extension browser page
11. **Enable Injection toggle** - turns on/off page script injection (on/off switch)
12. **Refresh View** - refreshes the popup view
13. **Available Updates View** - the extension periodically checks all userscripts in your save location for updates and when an update is found, it is shown in this view
@@ -121,53 +122,53 @@ After installing Userscripts on macOS, you **do not** need to select a userscrip
Userscripts Safari currently supports the following userscript metadata:
-- `@name` - This will be the name that displays in the sidebar and be used as the filename - you can *not* use the same name for multiple files of the same type
+- `@name` - This will be the name that displays in the sidebar and be used as the filename - you can _not_ use the same name for multiple files of the same type
- `@description`- Use this to describe what your userscript does - this will be displayed in the sidebar - there is a setting to hide descriptions
- `@icon` - This doesn't have a function with this userscript manager, but the **first value** provided in the metadata will be accessible in the `GM_/GM.info` object
- `@match` - Domain match patterns - you can use several instances of this field if you'd like multiple domain matches - view [this article for more information on constructing patterns](https://developer.chrome.com/extensions/match_patterns)
- - **Note:** this extension only supports `http/s`
-- `@exclude-match` - Domain patterns where you do *not* want the script to run
+ - **Note:** this extension only supports `http/s`
+- `@exclude-match` - Domain patterns where you do _not_ want the script to run
- `@include` - Used to match against urls for injection, globs and regular expressions are allowed, [read more here](https://wiki.greasespot.net/Include_and_exclude_rules)
- `@exclude` - Functions in a similar way as `@include` but rather than injecting, a match against this key's value will prevent injection
- `@inject-into` - allows the user to choose which context to inject the script into
- - allows the user to choose which context to inject the script into
- - values: `auto` (default), `content`, `page`
- - `GM` apis are only available when using `content`
- - works like [violentmonkey](https://violentmonkey.github.io/api/metadata-block/#inject-into)
+ - allows the user to choose which context to inject the script into
+ - values: `auto` (default), `content`, `page`
+ - `GM` apis are only available when using `content`
+ - works like [violentmonkey](https://violentmonkey.github.io/api/metadata-block/#inject-into)
- `@run-at`
- - allows the user to choose the injection timing
- - document-start, document-end (default), document-idle
- - works like [violentmonkey](https://violentmonkey.github.io/api/metadata-block/#run-at)
- - **JS Only**
+ - allows the user to choose the injection timing
+ - document-start, document-end (default), document-idle
+ - works like [violentmonkey](https://violentmonkey.github.io/api/metadata-block/#run-at)
+ - **JS Only**
- `@weight`
- - allows the user to further adjust script injection timing
- - can be used to ensure one script injects before another
- - ONLY accepts integers (floats, strings and everything else will be ignored)
- - min value = 1, max value = 999, higher numbers (“heavier”) execute earlier
+ - allows the user to further adjust script injection timing
+ - can be used to ensure one script injects before another
+ - ONLY accepts integers (floats, strings and everything else will be ignored)
+ - min value = 1, max value = 999, higher numbers (“heavier”) execute earlier
- `@require`
- - allows users to include remote resources in their scripts
- - the value must be a valid url, currently no local file support
- - must require a resource of the same file type (JS for JS, CSS for CSS)
- - when a resource is required, it is downloaded and saved locally
- - the resources is downloaded once at save and never checked for updates or parsed in anyway
- - if you want to update the require resources, and the url does not change, you must remove the resources, save, then re-input it
- - **require remote resources at your own risk, the extension never validates remote resource code in any way and be aware that using remote resources from untrusted sources can jeopardize your personal security**
+ - allows users to include remote resources in their scripts
+ - the value must be a valid url, currently no local file support
+ - must require a resource of the same file type (JS for JS, CSS for CSS)
+ - when a resource is required, it is downloaded and saved locally
+ - the resources is downloaded once at save and never checked for updates or parsed in anyway
+ - if you want to update the require resources, and the url does not change, you must remove the resources, save, then re-input it
+ - **require remote resources at your own risk, the extension never validates remote resource code in any way and be aware that using remote resources from untrusted sources can jeopardize your personal security**
- `@version`
- - used to determine the current version of a userscript
- - when paired with `@updateURL`, this will allow the user to update a userscript from a remote source, if the version on their machine is `<` version at the update URL
- - `@version` does nothing by itself, it needs to be paired with` @updateURL` for remote updating to function properly
+ - used to determine the current version of a userscript
+ - when paired with `@updateURL`, this will allow the user to update a userscript from a remote source, if the version on their machine is `<` version at the update URL
+ - `@version` does nothing by itself, it needs to be paired with` @updateURL` for remote updating to function properly
- `@updateURL`
- - the remote url to check version against
- - if the version of the file located at the update URL is `>` the version on the local machine, the file will be updated
- - `@updateURL` does nothing by itself, it needs to be paired with `@version` for remote updating to function properly
+ - the remote url to check version against
+ - if the version of the file located at the update URL is `>` the version on the local machine, the file will be updated
+ - `@updateURL` does nothing by itself, it needs to be paired with `@version` for remote updating to function properly
- `@downloadURL`
- - optional download location for a remotely updateable file (*i.e. a file that has both `@version` and `@updateURL`)
- - when paired with `@version` and `@updateURL`, if the local version is `<` the version of the file that `@updateURL` points to, the extension will attempt to update the file's code with the contents of the file located at the `@downloadURL`
- - `@downloadURL` does nothing by itself, it needs `@version` and `@updateURL` to present in order to function properly
+ - optional download location for a remotely updateable file (\*i.e. a file that has both `@version` and `@updateURL`)
+ - when paired with `@version` and `@updateURL`, if the local version is `<` the version of the file that `@updateURL` points to, the extension will attempt to update the file's code with the contents of the file located at the `@downloadURL`
+ - `@downloadURL` does nothing by itself, it needs `@version` and `@updateURL` to present in order to function properly
- `@noframes`
- - this key takes no value
- - prevents code from being injected into nested frames
-
+ - this key takes no value
+ - prevents code from being injected into nested frames
+
**All userscripts need at least 1 `@match` or `@include` to run!**
## API
@@ -175,95 +176,97 @@ Userscripts Safari currently supports the following userscript metadata:
Userscripts currently supports the following api methods. All methods are asynchronous unless otherwise noted. Users must `@grant` these methods in order to use them in a userscript. When using API methods, it's only possible to inject into the content script scope due to security concerns.
- `GM.addStyle(css)`
- - `css: String`
- - on success returns a promise resolved with the css string argument provided
+ - `css: String`
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved if succeeds, rejected with error message if fails
- `GM.setValue(key, value)`
- - `key: String`, `value: Any`
- - on success returns a promise resolved with an object indicating success
+ - `key: String`
+ - `value: Any` - any can be JSON-serialized
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved if succeeds, rejected with error message if fails
- `GM.getValue(key, defaultValue)`
- - `key: String`, `defaultValue: Any`
- - on success returns a promise resolved with the value that was set or default value provided
+ - `key: String`
+ - `defaultValue: Any` - optional
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved with the `value` that was set or `defaultValue` provided or `undefined` if succeeds, rejected with error message if fails
- `GM.deleteValue(key)`
- - `key: String`
- - on success returns a promise resolved with an object indicating success
+ - `key: String`
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved if succeeds, rejected with error message if fails
- `GM.listValues()`
- - on success returns a promise resolved with an array of the key names of **presently set** values
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved with an array of the key names of **presently set** values if succeeds, rejected with error message if fails
- `GM.getTab()`
- - on success returns a promise resolved with `Any` data that is persistent as long as this tab is open
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved with `Any` data that is persistent as long as this tab is open if succeeds, rejected with error message if fails
- `GM.saveTab(tabObj)`
- - `tabObj: Any`
- - on success returns a promise resolved with an object indicating success
+ - `tabObj: Any` - any can be JSON-serialized
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved if succeeds, rejected with error message if fails
- `GM.openInTab(url, openInBackground)`
- - `url: String`, `openInBackground: Bool`
- - on success returns a promise resolved with the [tab data](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab) for the tab just opened
+ - `url: String`
+ - `openInBackground: Bool` - optional, `false` by default
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved with [tab data](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab) for the tab just opened if succeeds, rejected with error message if fails
- `GM.closeTab(tabId)`
- - `tabId: Int`
- - `tabId` is **optional** and if omitted the tab that called `US.closeTab` will be closed
- - on success returns a promise resolved with an object indicating success
+ - `tabId: Int` - optional, the `caller tab` by default
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved if succeeds, rejected with error message if fails
- `GM.setClipboard(data, type)`
- - `data: String` - **required**
- - `type: String` - **optional** and defaults to `text/plain`
- - [read more here](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData)
- - on success returns a promise resolved with a `Bool` indicating success
+ - `data: String`
+ - `type: String` - optional, `text/plain` by default
+ - [read more here](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData)
+ - returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), resolved with a `Bool` value indicating succeeds or fails, rejected with error message if fails
- `GM.info` && `GM_info`
- - is available without needing to add it to `@grant`
- - an object containing information about the running userscript
- - `scriptHandler: String` - returns `Userscripts`
- - `version: String` - the version of Userscripts app
- - `scriptMetaStr: String` - the metablock for the currently running script
- - `script: Object` - contains data about the currently running script
- - `description: String`
- - `exclude-match: [String]`
- - `excludes: [String]`
- - `grant: [String]`
- - `includes: [String]`
- - `inject-into: String`
- - `matches: [String]`
- - `name: String`
- - `namespace: String`
- - `noframes: Bool`
- - `require: [String]`
- - `resources: [String]` - *currently not implemented*
- - `run-at: String`
- - `version: String` - *the userscript version value*
+ - is available without needing to add it to `@grant`
+ - an object containing information about the running userscript
+ - `scriptHandler: String` - returns `Userscripts`
+ - `version: String` - the version of Userscripts app
+ - `scriptMetaStr: String` - the metablock for the currently running script
+ - `script: Object` - contains data about the currently running script
+ - `description: String`
+ - `exclude-match: [String]`
+ - `excludes: [String]`
+ - `grant: [String]`
+ - `includes: [String]`
+ - `inject-into: String`
+ - `matches: [String]`
+ - `name: String`
+ - `namespace: String`
+ - `noframes: Bool`
+ - `require: [String]`
+ - `resources: [String]` - _currently not implemented_
+ - `run-at: String`
+ - `version: String` - _the userscript version value_
- `GM.xmlHttpRequest(details)`
- - `details: Object`
- - the `details` object accepts the following properties
- - `url` - `String` - **required**
- - `method` - `String` - defaults to `GET`
- - `user` - `String`
- - `password` - `String`
- - `headers` - `Object`
- - `overrideMimeType`
- - `timeout` - `Int`
- - `binary` - `Bool`
- - `data` - `String`
- - `responseType` - `String`
- - read more about [XMLHttpRequests here](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
- - event handlers:
- - `onabort` - `function`
- - `onerror` - `function`
- - `onload` - `function`
- - `onloadend` - `function`
- - `onloadstart` - `function`
- - `onprogress` - `function`
- - `onreadystatechange` - `function`
- - `ontimeout` - `function`
- - the response object passed to the event handlers has the following properties:
- - `readyState`
- - `response`
- - `responseHeaders`
- - `responseType`
- - `responseURL`
- - `status`
- - `statusText`
- - `timeout`
- - `withCredentials`
- - `responseText` (when `responseType` is `text`)
- - returns an object with a single property, `abort`, which is a `function`
- - usage: `const foo = GM.xmlHttpRequest({...});` ... `foo.abort()` to abort the request
+ - `details: Object`
+ - the `details` object accepts the following properties
+ - `url: String` - required
+ - `method: String` - optional, `GET` by default
+ - `user: String` - optional
+ - `password: String` - optional
+ - `headers: Object` - optional
+ - `overrideMimeTyp: String` - optional
+ - `timeout: Int` - optional
+ - `binary: Bool` - optional
+ - `data: String` - optional
+ - `responseType: String` - optional
+ - refer to [`XMLHttpRequests`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
+ - event handlers:
+ - `onabort: Function` - optional
+ - `onerror: Function` - optional
+ - `onload: Function` - optional
+ - `onloadend: Function` - optional
+ - `onloadstart: Function` - optional
+ - `onprogress: Function` - optional
+ - `onreadystatechange: Function` - optional
+ - `ontimeout: Function` - optional
+ - the response object passed to the event handlers has the following properties:
+ - `readyState`
+ - `response`
+ - `responseHeaders`
+ - `responseType`
+ - `responseURL`
+ - `status`
+ - `statusText`
+ - `timeout`
+ - `withCredentials`
+ - `responseText` (when `responseType` is `text`)
+ - returns an object with a single property, `abort`, which is a `Function`
+ - usage: `const foo = GM.xmlHttpRequest({...});` ... `foo.abort();` to abort the request
- `GM_xmlhttpRequest(details)`
- - an alias for `GM.xmlHttpRequest`, works exactly the same
+ - an alias for `GM.xmlHttpRequest`, works exactly the same
## Scripts Directory
@@ -277,7 +280,7 @@ This is the directory where the app/extension will read from and write to. This
## Getting Help
-If you encounter a problem while using this app/extension or are in need of some assistance, please open an issue here in the repository. When doing so, please provide as much detail as possible. This includes listing system specs and what website and script you are trying to execute. *Please follow the issue template!*
+If you encounter a problem while using this app/extension or are in need of some assistance, please open an issue here in the repository. When doing so, please provide as much detail as possible. This includes listing system specs and what website and script you are trying to execute. _Please follow the issue template!_
## FAQs
@@ -299,22 +302,25 @@ If you encounter a problem while using this app/extension or are in need of some
**When I use `@require`, where are the required files stored?**
-> All required files are saved *as Javascript files* in the extension container folder in macOS 11.x. That folder is located in the default save location, at: `~/Library/Containers/Userscripts/Data/Documents/require/`.
+> All required files are saved _as Javascript files_ in the extension container folder in macOS 11.x. That folder is located in the default save location, at: `~/Library/Containers/Userscripts/Data/Documents/require/`.
>
> If you move files from the require folder or manually edit the `manifest.json` file, you will likely break app/extension functionality.
## Contributing
-Code level contributions are welcome. *I prefer to collaborate directly with contributors rather than receiving spontaneous pull requests*. If you feel you can improve the project in some way, please reach out to me by email or by opening an issue with your improvement/feature request.
+
+Code level contributions are welcome. _I prefer to collaborate directly with contributors rather than receiving spontaneous pull requests_. If you feel you can improve the project in some way, please reach out to me by email or by opening an issue with your improvement/feature request.
Further, any issue marked "help wanted" is actively seeking assistance. Please respond to those issues with feedback, guidance or offers of coding assistance.
Notes:
+
- use [semantic commit messages](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716)
- under most circumstances, you should fork the most current version of the `develop` branch for your contributions
**Please ensure your contributions align with the project's license before committing anything.**
## Support
+
The quickest and easiest way to support the project is by [leaving a positive review on the App Store](https://apps.apple.com/us/app/userscripts/id1463298887) if you enjoy the extension and want to see future improvements. Seeing these reviews let me know I am doing something right, or wrong, and motivates me to continue working on the project.
The second best way to help out is to sign up to beta test new versions of the app. Since this extension values your privacy, and **does not collect any data from users**, it is difficult to gauge how the extension is being used. By signing up to be a beta tester it not only allows you to test upcoming features, but also gives me the opportunity to elicit direct feedback from real users.
@@ -324,10 +330,11 @@ The second best way to help out is to sign up to beta test new versions of the a
**[macOS Beta Sign Up Form](https://forms.gle/cUDtKg1ip4Vc9Xhc7)**
## Privacy Policy
+
Userscripts does not collect any data from its users nor monitor activities or actions you perform within the application and extension. This means everything that you do with the application and extension is private to you and is never shared with the developers or third parties. Since there is no data collection, there is no data retention of any kind.
## License
-Copyright (c) 2022 Justin Wasack
+Copyright (c) 2018-2023 Justin Wasack
Licensed under the [GNU General Public License v3.0](/LICENSE) license for all open source applications. A commercial license is required for all other applications.
diff --git a/docs/contributing.md b/docs/contributing.md
index b039ead6..5b2c616b 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -6,11 +6,16 @@ We hope this guide will helps you understand how to contribute to this project.
For development and build environments please refer to [development guide](dev.md).
-**Note: Portions of this guide are outdated. Some processes are still being tweaked and optimized, we will update them in due course.**
+> [!NOTE]
+> Portions of this guide are outdated. Some processes are still being tweaked and optimized, we will update them in due course.
+
+> [!IMPORTANT]
+> Any pull requests must first go through code formatting and linters, otherwise you will fail the CI check. Refer to the `scripts` in [`package.json`](../package.json)
# Branches
### `main`: default branch
+
- corresponding to development channel
- all development work around this branch
- protected branches not accept commits
@@ -18,6 +23,7 @@ For development and build environments please refer to [development guide](dev.m
- all sub-branches will be merged via PRs
### `beta`: latest test version
+
- generated from the master branch
- corresponding to TestFlight channel
- only accept version number commits
@@ -25,6 +31,7 @@ For development and build environments please refer to [development guide](dev.m
- never merge back into master branch
### `release`: latest public version
+
- generated from the beta branch
- generate GitHub Releases and Tags
- corresponding to App Store channel
@@ -32,6 +39,7 @@ For development and build environments please refer to [development guide](dev.m
- always merge back into master branch
# Commits
+
### Please use semantic commit messages
Format: `- This is the development preview environment -
-+ You can turn on the Userscripts iOS Safari extension in Settings. + + Read the docs. + +
+ ++ + native-app + , + + action-popup + , + + extension-page + +
+ +This is the development preview environment
+Welcome, first use please:
+ +to complete the initialization
+{installError}
+Be sure you trust the author before saving remote code to your device.
+ +{:else} +
+ Userscripts Safari Version {$settings.version} ({$settings.build})
+
+ You can review the documentation, report bugs and get more information about
+ this extension by visiting
+
+
+ If you enjoy using this extension, please consider
+
+ on the App Store or
+
+
- Userscripts Safari Version {$settings.version} ({$settings.build})
-
- You can review the documentation, report bugs and get more information about this extension by visiting
-
-
- If you enjoy using this extension, please consider
-
- on the App Store or
-
-
{installError}
-Be sure you trust the author before saving remote code to your device.
- -{:else} -You can turn on the Userscripts iOS Safari extension in Settings. Read the docs.