Compare commits
11 Commits
0.13.3
...
macosintel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9a54c7e68 | ||
|
|
292362135d | ||
|
|
aae5434451 | ||
|
|
2390530d92 | ||
|
|
9ab3ff75b0 | ||
|
|
d25c4e8c81 | ||
|
|
4a7efa27c8 | ||
|
|
cec0b4b4f6 | ||
|
|
a1922c50c1 | ||
|
|
870120bc13 | ||
|
|
f38cf73485 |
57
.github/ISSUE_TEMPLATE/1-bug-report-scripts.md
vendored
57
.github/ISSUE_TEMPLATE/1-bug-report-scripts.md
vendored
@@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report (script bug or unexpected script behavior)
|
|
||||||
about: Create a bug report for generated scripts to help privacy.sexy improve
|
|
||||||
labels: bug
|
|
||||||
title: '[BUG]: '
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Thank you for reporting an issue with generated script(s).
|
|
||||||
Please fill in as much of the template below as you're able.
|
|
||||||
As a small open source project with small community, it can sometimes take a long time for issues to be addressed so please be patient.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### OS
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Which OS are you using? What version of OS you were using?
|
|
||||||
On Windows: Open "Start button" > "Settings" > "System" > "About".
|
|
||||||
On macOS: Open "Apple menu (top left corner)" > "About This Mac".
|
|
||||||
On Linux: Open terminal > type: lsb_release -a > copy paste the result.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Reproduction steps
|
|
||||||
|
|
||||||
<!--
|
|
||||||
How can the bug be recreated?
|
|
||||||
It's the most important information in the bug report. Bugs that cannot be reproduced cannot be fixed and verified.
|
|
||||||
E.g.
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Scripts
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, please attach the generated privacy.sexy file instead of copy pasting which becomes too long.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Screenshots
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Additional information
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, add any other context about the problem here.
|
|
||||||
-->
|
|
||||||
114
.github/ISSUE_TEMPLATE/1-bug-report-scripts.yaml
vendored
Normal file
114
.github/ISSUE_TEMPLATE/1-bug-report-scripts.yaml
vendored
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
name: "Bug Report: Script Issues"
|
||||||
|
description: 🐛 Report issues with generated scripts to enhance privacy.sexy
|
||||||
|
labels: [ 'bug' ]
|
||||||
|
title: '[Bug]: '
|
||||||
|
body:
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
Thank you for contributing to privacy.sexy and guiding our direction! 🌟
|
||||||
|
Please complete as much of the form below as possible.
|
||||||
|
Your feedback is valuable, even if you can't provide all details.
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear and concise description of what the bug is.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "After running the cleanup script, music playback stopped functioning."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: How can the bug be recreated?
|
||||||
|
description: |-
|
||||||
|
This is the most important information in the bug report.
|
||||||
|
Bugs that cannot be reproduced cannot be fixed or verified.
|
||||||
|
placeholder: |-
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Operating system
|
||||||
|
description: |-
|
||||||
|
Please specify your operating system and its version.
|
||||||
|
|
||||||
|
- On Windows: Open "Start button" > "Settings" > "System" > "About".
|
||||||
|
- On macOS: Open "Apple menu (top left corner)" > "About This Mac".
|
||||||
|
- On Linux: Open terminal > type: lsb_release -a > copy paste the result.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Windows 11 Pro 22H3"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Script file
|
||||||
|
description: |-
|
||||||
|
If applicable, share the generated privacy.sexy file.
|
||||||
|
|
||||||
|
GitHub may restrict script file attachments.
|
||||||
|
Upload your script file to a service like [GitHub Gist](https://gist.github.com/) and share the link here.
|
||||||
|
|
||||||
|
If you used the desktop version to run the script, it is already stored on your system.
|
||||||
|
See the [documentation to locate it](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/desktop/desktop-vs-web-features.md#secure-script-executionstorage).
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach script files by dragging them into this area.
|
||||||
|
placeholder: |-
|
||||||
|
Attach the script, or post GitHub Gist link.
|
||||||
|
For example: https://gist.github.com/privacysexy-forks/6d85ad8ca27acc8c6a5417d4af28c9b6.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Screenshots
|
||||||
|
description: |-
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach screenshots by clicking this area to highlight it and then pasting them or dragging files in.
|
||||||
|
placeholder: Attach screenshots here or link to image hosting.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional information
|
||||||
|
description: |-
|
||||||
|
If applicable, add any other context about the problem here.
|
||||||
|
|
||||||
|
Helpful information includes:
|
||||||
|
|
||||||
|
- Application logs (desktop version only), see: [how to find application logs](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/desktop/desktop-vs-web-features.md#logging).
|
||||||
|
- Terminal output
|
||||||
|
- Proposed solutions
|
||||||
|
- Other related context such as related issues, software behavior, etc.
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach log files by dragging them into this area.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Here are the logs I get from the privacy.sexy 0.13.2 desktop application: ..."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
---
|
||||||
|
|
||||||
|
**✉️ A friendly note from the maintainer:**
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> We are a small open-source project with a small community.
|
||||||
|
> It can sometimes take a long time for issues to be addressed, so please be patient.
|
||||||
|
> Consider [donating](https://undergroundwires.dev/donate) to keep privacy.sexy alive and improve support ❤️.
|
||||||
|
> But your issue will eventually get attention regardless.
|
||||||
|
> <p align="right">@undergroundwires</p>
|
||||||
|
|
||||||
|
---
|
||||||
104
.github/ISSUE_TEMPLATE/2-bug-report-general.yaml
vendored
Normal file
104
.github/ISSUE_TEMPLATE/2-bug-report-general.yaml
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
name: "Bug Report: General"
|
||||||
|
description: 🐛 Report general issues to enhance privacy.sexy
|
||||||
|
labels: [ 'bug' ]
|
||||||
|
title: '[Bug]: '
|
||||||
|
body:
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
Thank you for contributing to privacy.sexy and guiding our direction! 🌟
|
||||||
|
Please complete as much of the form below as possible.
|
||||||
|
Your feedback is valuable, even if you can't provide all details.
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: Provide a clear and concise description of the issue.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "I cannot select any scripts."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Reproduction steps
|
||||||
|
description: |-
|
||||||
|
This is the most important information in the bug report.
|
||||||
|
Bugs that cannot be reproduced cannot be fixed or verified.
|
||||||
|
placeholder: |-
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: Describe what you expected to happen when the error occurred.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "I expected the settings menu to open smoothly without crashing.".
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Screenshots
|
||||||
|
description: |-
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach screenshots by clicking this area to highlight it and then pasting them or dragging files in.
|
||||||
|
placeholder: >-
|
||||||
|
Attach screenshots here or link to image hosting.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: privacy.sexy environment details
|
||||||
|
description: |-
|
||||||
|
If applicable, mention how you were using privacy.sexy when the bug occurred:
|
||||||
|
|
||||||
|
- Web (on which operating system and browser?)
|
||||||
|
- Or desktop (Windows, macOS, or Linux?)
|
||||||
|
placeholder: >-
|
||||||
|
For example: "The web version on Edge browser on Windows 11 23H2."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: |-
|
||||||
|
If applicable, add any other context about the problem here.
|
||||||
|
|
||||||
|
Helpful information includes:
|
||||||
|
|
||||||
|
- Application logs (desktop version only), see: [how to find application logs](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/desktop/desktop-vs-web-features.md#logging).
|
||||||
|
- Terminal output
|
||||||
|
- Proposed solutions
|
||||||
|
- Other related context such as related issues, software behavior, etc.
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach log files by dragging them into this area.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Here are the logs I get from the privacy.sexy 0.13.2 desktop application: ..."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
---
|
||||||
|
|
||||||
|
**✉️ A friendly note from the maintainer:**
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> We are a small open-source project with a small community.
|
||||||
|
> It can sometimes take a long time for issues to be addressed, so please be patient.
|
||||||
|
> Consider [donating](https://undergroundwires.dev/donate) to keep privacy.sexy alive and improve support ❤️.
|
||||||
|
> But your issue will eventually get attention regardless.
|
||||||
|
> <p align="right">@undergroundwires</p>
|
||||||
|
|
||||||
|
---
|
||||||
55
.github/ISSUE_TEMPLATE/2-bug-report-generic.md
vendored
55
.github/ISSUE_TEMPLATE/2-bug-report-generic.md
vendored
@@ -1,55 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report (unrelated to generated scripts)
|
|
||||||
about: Create a bug report that's not related to generated scripts to help privacy.sexy improve
|
|
||||||
labels: bug
|
|
||||||
title: '[BUG]: '
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Thank you for reporting an issue.
|
|
||||||
Please fill in as much of the template below as you're able.
|
|
||||||
As a small open source project with small community, it can sometimes take a long time for issues to be addressed so please be patient.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Reproduction steps
|
|
||||||
|
|
||||||
<!--
|
|
||||||
It's the most important information in the bug report. Bugs that cannot be reproduced cannot be fixed and verified.
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Expected behavior
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Screenshots
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Distribution
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, mention how you were using privacy.sexy when the bug was encountered:
|
|
||||||
- Web (on Desktop or mobile?)
|
|
||||||
- Or desktop (Windows, macOS or Linux?)
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Additional context
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, add any other context about the problem here.
|
|
||||||
-->
|
|
||||||
36
.github/ISSUE_TEMPLATE/3-feature-request.md
vendored
36
.github/ISSUE_TEMPLATE/3-feature-request.md
vendored
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for privacy.sexy
|
|
||||||
labels: enhancement
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Thank you for suggesting an idea to improve privacy better 🤗.
|
|
||||||
Please fill in as much of the template below as you're able.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Problem description
|
|
||||||
|
|
||||||
<!--
|
|
||||||
What are we trying to solve?
|
|
||||||
Please add a clear and concise description of the problem you are seeking to solve with this feature request.
|
|
||||||
E.g. I'm always frustrated when [...]
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Proposed solution
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Describe the solution you'd like in a clear and concise manner.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Alternatives considered
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Additional information
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If applicable, add any other context or screenshots about the feature request here.
|
|
||||||
-->
|
|
||||||
73
.github/ISSUE_TEMPLATE/3-suggestion-feature.yaml
vendored
Normal file
73
.github/ISSUE_TEMPLATE/3-suggestion-feature.yaml
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
name: "Suggestion: Feature"
|
||||||
|
description: 💡 Suggest new ideas to enhance privacy.sexy
|
||||||
|
labels: [ 'enhancement' ]
|
||||||
|
title: '[Feature]: '
|
||||||
|
body:
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
Thank you for contributing to privacy.sexy and guiding our direction! 🌟
|
||||||
|
Please complete as much of the form below as possible.
|
||||||
|
Your feedback is valuable, even if you can't provide all details.
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Problem statement
|
||||||
|
description: |-
|
||||||
|
What are we trying to solve?
|
||||||
|
|
||||||
|
Please add a clear and concise description of the problem you are seeking to solve with this feature request.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Every time I use the app, I struggle with..."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Proposed solution
|
||||||
|
description: |-
|
||||||
|
Describe the solution you'd like in a clear and concise manner.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "It would be great if the app could..."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Alternatives considered
|
||||||
|
description: |-
|
||||||
|
Have you considered any alternative solutions or features?
|
||||||
|
Different perspectives can inspire new ideas.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "We could also solve it by...".
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional information
|
||||||
|
description: |-
|
||||||
|
If applicable, add any other context or screenshots about the feature request here.
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach files or screenshots by dragging them into this area.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Challenges can be ..., but I'm unsure about ..., here is some documentation about it: ..."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
---
|
||||||
|
|
||||||
|
**✉️ A friendly note from the maintainer:**
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> We are a small open-source project with a small community.
|
||||||
|
> It can sometimes take a long time for issues to be addressed, so please be patient.
|
||||||
|
> Consider [donating](https://undergroundwires.dev/donate) to keep privacy.sexy alive and improve support ❤️.
|
||||||
|
> But your issue will eventually get attention regardless.
|
||||||
|
> <p align="right">@undergroundwires</p>
|
||||||
|
|
||||||
|
---
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
name: New script suggestion
|
|
||||||
about: Suggest a new script for privacy.sexy
|
|
||||||
labels: enhancement
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Thank you for contributing to privacy.sexy! 🌟
|
|
||||||
For guidance, see our script guidelines: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md.
|
|
||||||
Consider submitting a PR for faster implementation: https://github.com/undergroundwires/privacy.sexy/blob/master/CONTRIBUTING.md#extend-scripts.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Operating system
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Specify the OS: Windows, macOS, or Linux.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Name
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Suggest a name for the script.
|
|
||||||
Naming conventions: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#name.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Code
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Provide or explain the code to execute when the script runs.
|
|
||||||
Code guidelines: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#code.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Revert code
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Include code to revert changes to the default state.
|
|
||||||
Leave blank for non-reversible scripts.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Category
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Suggest a category for the script.
|
|
||||||
If unsure, leave blank for maintainers to decide.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Recommendation level
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Suggest a recommendation level: STANDARD (non-breaking), STRICT (limits functionality), or NONE (for advanced users).
|
|
||||||
If unsure, leave blank for maintainers to decide.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Documentation/References
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Provide any relevant documentation or references.
|
|
||||||
Prefer high-quality sources such as vendor documentation.
|
|
||||||
Documentation guidelines: https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#documentation.
|
|
||||||
-->
|
|
||||||
133
.github/ISSUE_TEMPLATE/4-suggestion-new-script.yaml
vendored
Normal file
133
.github/ISSUE_TEMPLATE/4-suggestion-new-script.yaml
vendored
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
name: "Suggestion: New Script"
|
||||||
|
description: 💡 Suggest new scripts to enhance privacy.sexy
|
||||||
|
labels: [ 'enhancement' ]
|
||||||
|
title: '[New script]: '
|
||||||
|
body:
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
Thank you for contributing to privacy.sexy and guiding our direction! 🌟
|
||||||
|
Please complete as much of the form below as possible.
|
||||||
|
Your feedback is valuable, even if you can't provide all details.
|
||||||
|
|
||||||
|
For guidance, see our [script guidelines](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md).
|
||||||
|
Consider submitting a PR to get your script added more quickly: (see [CONTRIBUTING.md](https://github.com/undergroundwires/privacy.sexy/blob/master/CONTRIBUTING.md#extend-scripts))
|
||||||
|
-
|
||||||
|
type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Operating system
|
||||||
|
description: Which operating system will the new script configure?
|
||||||
|
options:
|
||||||
|
- macOS
|
||||||
|
- Windows
|
||||||
|
- Linux
|
||||||
|
- All of them
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Name of the script
|
||||||
|
description: |-
|
||||||
|
Suggest a name for the script that clearly describes its function.
|
||||||
|
|
||||||
|
See [script naming conventions](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#name) for best practices.
|
||||||
|
placeholder: E.g, "Disable error data submission"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Documentation/References
|
||||||
|
description: |-
|
||||||
|
Provide any relevant documentation or references.
|
||||||
|
Prefer high-quality sources such as vendor documentation.
|
||||||
|
|
||||||
|
See [documentation guidelines](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#documentation) for best practices.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "This script will disable the error data submission, see https://microsoft.com/...".
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Code
|
||||||
|
description: |-
|
||||||
|
If possible, provide or explain the code that the script should execute.
|
||||||
|
|
||||||
|
See [script code guidelines](https://github.com/undergroundwires/privacy.sexy/blob/master/docs/script-guidelines.md#code).
|
||||||
|
placeholder: |-
|
||||||
|
For example: "Set registry key like this `reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" /v "AllowTelemetry" /t "REG_DWORD" /d "1"`".
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Revert code
|
||||||
|
description: |-
|
||||||
|
If applicable, provide revert code to restore the changes made by the script.
|
||||||
|
|
||||||
|
The revert code restores changes to their default state before script execution.
|
||||||
|
|
||||||
|
Leave blank for non-reversible scripts.
|
||||||
|
placeholder: |-
|
||||||
|
For example: "Revert to operating system default like this `reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" /v "AllowTelemetry" /t "REG_DWORD" /d "0"`".
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Suggested category
|
||||||
|
description: |-
|
||||||
|
Suggest a category for the script.
|
||||||
|
|
||||||
|
If unsure, leave blank for maintainers to decide.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Privacy Cleanup > Clear system logs"
|
||||||
|
-
|
||||||
|
type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Recommendation level
|
||||||
|
description: |-
|
||||||
|
Suggest a recommendation level for the script:
|
||||||
|
|
||||||
|
- **Standard**: Recommended for most users without side-effects.
|
||||||
|
- **Strict**: Provides improved privacy at the cost of some functionality.
|
||||||
|
- **None**: For advanced users or specific needs.
|
||||||
|
|
||||||
|
If unsure, leave blank for maintainers to decide.
|
||||||
|
options:
|
||||||
|
- Standard
|
||||||
|
- Strict
|
||||||
|
- None (do not recommend)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional information
|
||||||
|
description: |-
|
||||||
|
If applicable, add any other context or screenshots about the script request here.
|
||||||
|
|
||||||
|
> **💡 Tip:** You can attach additional documents or screenshots by dragging them into this area or pasting directly.
|
||||||
|
placeholder: >-
|
||||||
|
For example: "Challenges can be ..., but I am unsure about ..."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
-
|
||||||
|
type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |-
|
||||||
|
---
|
||||||
|
|
||||||
|
**✉️ A friendly note from the maintainer:**
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> We are a small open-source project with a small community.
|
||||||
|
> It can sometimes take a long time for issues to be addressed, so please be patient.
|
||||||
|
> Consider [donating](https://undergroundwires.dev/donate) to keep privacy.sexy alive and improve support ❤️.
|
||||||
|
> But your issue will eventually get attention regardless.
|
||||||
|
> <p align="right">@undergroundwires</p>
|
||||||
|
|
||||||
|
---
|
||||||
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1 +1,7 @@
|
|||||||
|
# This file must be named `config.yml`. GitHub does not recognize the file if it is named `config.yaml`.
|
||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
|
contact_links:
|
||||||
|
- name: Donate
|
||||||
|
url: https://undergroundwires.dev/donate/
|
||||||
|
about: ❤️ Donate to support the free software you love to keep it alive.
|
||||||
|
# A separate link for reporting vulnerabilities is not included here because GitHub generates it automatically.
|
||||||
|
|||||||
23
.github/workflows/checks.build.yaml
vendored
23
.github/workflows/checks.build.yaml
vendored
@@ -72,20 +72,35 @@ jobs:
|
|||||||
build-docker:
|
build-docker:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ macos, ubuntu ] # Windows runners do not support Linux containers
|
os:
|
||||||
|
- macos-13 # Downgraded due to lack of nested virtualization support in ARM-based runners (See: actions/runner-images#9460, actions/runner-images#9741, abiosoft/colima#1023)
|
||||||
|
- ubuntu-latest
|
||||||
|
# - windows-latest # Windows runners do not support Linux containers
|
||||||
fail-fast: false # Allows to see results from other combinations
|
fail-fast: false # Allows to see results from other combinations
|
||||||
runs-on: ${{ matrix.os }}-latest
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: Install Docker on macOS
|
name: Install Docker on macOS
|
||||||
if: matrix.os == 'macos' # macOS runner is missing Docker
|
if: contains(matrix.os, 'macos') # macOS runner is missing Docker
|
||||||
run: |-
|
run: |-
|
||||||
|
# Verify Intel-based macOS
|
||||||
|
arch=$(uname -m)
|
||||||
|
case "$arch" in
|
||||||
|
i386|x86_64)
|
||||||
|
echo "Supported architecture: $arch"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
>&2 echo 'The macOS is not running on a supported Intel architecture. Virtualization is not supported.'
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
# Install Docker
|
# Install Docker
|
||||||
brew install docker
|
brew install docker
|
||||||
# Docker on macOS misses daemon due to licensing, so install colima as runtime
|
# Docker on macOS does not include the Docker daemon due to licensing issues.
|
||||||
|
# Install Colima to use as the Docker runtime.
|
||||||
brew install colima
|
brew install colima
|
||||||
# Start the daemon
|
# Start the daemon
|
||||||
colima start
|
colima start
|
||||||
|
|||||||
@@ -9,9 +9,13 @@ jobs:
|
|||||||
run-check:
|
run-check:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ macos, ubuntu, windows ]
|
os:
|
||||||
|
- macos-latest # Latest Apple silicon (ARM64)
|
||||||
|
- macos-12 # Latest Intel-based (x86-64)
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
fail-fast: false # Allows to see results from other combinations
|
fail-fast: false # Allows to see results from other combinations
|
||||||
runs-on: ${{ matrix.os }}-latest
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
@@ -24,7 +28,7 @@ jobs:
|
|||||||
uses: ./.github/actions/npm-install-dependencies
|
uses: ./.github/actions/npm-install-dependencies
|
||||||
-
|
-
|
||||||
name: Configure Ubuntu
|
name: Configure Ubuntu
|
||||||
if: matrix.os == 'ubuntu'
|
if: contains(matrix.os, 'ubuntu') # macOS runner is missing Docker
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |-
|
run: |-
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
|||||||
2
.github/workflows/checks.quality.yaml
vendored
2
.github/workflows/checks.quality.yaml
vendored
@@ -4,7 +4,7 @@ on: [ push, pull_request ]
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
lint-command:
|
lint-command:
|
||||||
|
|||||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,5 +1,32 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.13.3 (2024-05-11)
|
||||||
|
|
||||||
|
* win: organize and document network disablement | [2eed6f4](https://github.com/undergroundwires/privacy.sexy/commit/2eed6f4afb6cf85fdc1d6acb808f82405a35cafd)
|
||||||
|
* win: improve disabling SMBv1 protocol | [f584fab](https://github.com/undergroundwires/privacy.sexy/commit/f584fabb50c7de70ba43751d721af94d8fa2fa8a)
|
||||||
|
* win: improve disabling insecure renegotiations | [f261ab4](https://github.com/undergroundwires/privacy.sexy/commit/f261ab4cd9a53e31325e5c6da9129542971fe84b)
|
||||||
|
* win: doc, improve, encourage cipher disabling | [8b224ee](https://github.com/undergroundwires/privacy.sexy/commit/8b224eefe71be6a556a1085d8fe20dbd4b889430)
|
||||||
|
* ci/cd: add check for TODO comments | [4e21f05](https://github.com/undergroundwires/privacy.sexy/commit/4e21f05031d6cc90cda684bd598bec4735f8103b)
|
||||||
|
* win: improve 'Snipping Tool' removal #343 | [e18907c](https://github.com/undergroundwires/privacy.sexy/commit/e18907ca91e483255b44d14d7d923d7eef92afbd)
|
||||||
|
* ci/cd: lint Python scripts using `pylint` | [23bac0f](https://github.com/undergroundwires/privacy.sexy/commit/23bac0fc76ad697abb34f3fb327df5cdeb40286a)
|
||||||
|
* win: improve disabling insecure hashes #131 | [d19dde6](https://github.com/undergroundwires/privacy.sexy/commit/d19dde603ddac47022ee2e0ea865d53857560c26)
|
||||||
|
* Add system requirements documentation #134 | [0fc2ffc](https://github.com/undergroundwires/privacy.sexy/commit/0fc2ffc1ea36a9248c6a92da85a29f7b04b33796)
|
||||||
|
* win, linux, mac: fix various typos #349 | [694bf1a](https://github.com/undergroundwires/privacy.sexy/commit/694bf1a74d935531d7cd46891823af1fa58c3c8c)
|
||||||
|
* Fix script cancellation with new dialog on Linux | [8c17396](https://github.com/undergroundwires/privacy.sexy/commit/8c173962857a39dc0c9e5886cb2af4937e6618e7)
|
||||||
|
* win: improve disabling protocols | [4ef16ce](https://github.com/undergroundwires/privacy.sexy/commit/4ef16cea56789120cd041412d86b5577cccf0725)
|
||||||
|
* win: fix Copilot by excluding `r.bing.com` #329 | [66a5688](https://github.com/undergroundwires/privacy.sexy/commit/66a56888a4b3ead1a6bfef0feffa0218535701fe)
|
||||||
|
* Fix blank window on load on desktop version #348 | [813d820](https://github.com/undergroundwires/privacy.sexy/commit/813d820b85e1b623c50f8e0325ad372bf2f344f9)
|
||||||
|
* Improve desktop icon quality and generation | [ab25e0a](https://github.com/undergroundwires/privacy.sexy/commit/ab25e0a066be14ea979dafd0f80e1091bd5d33f8)
|
||||||
|
* win: improve enabling secure connections #175 | [c75df1c](https://github.com/undergroundwires/privacy.sexy/commit/c75df1c8c1151b64cbf014383dea0b748a8c78b3)
|
||||||
|
* Fix VSCode script issues with added CI/CD tests | [1d7cafc](https://github.com/undergroundwires/privacy.sexy/commit/1d7cafc831dcc339a10646794410dad7096bfe60)
|
||||||
|
* Fix win execution with whitespace in username #351 | [a334320](https://github.com/undergroundwires/privacy.sexy/commit/a3343205b1196d5a81fd3cee2ae661ce871a7bef)
|
||||||
|
* Fix misaligned tooltip positions in modal dialogs | [dd71536](https://github.com/undergroundwires/privacy.sexy/commit/dd71536316ec819caeb418b8635d544ac80e58ad)
|
||||||
|
* Fix Chromium scrollbar-induced layout shifts | [bc4879c](https://github.com/undergroundwires/privacy.sexy/commit/bc4879cfe97becac3c54f6b40780a89464d3b772)
|
||||||
|
* ci/cd: remove `check-latest` from `setup-node` | [52a4730](https://github.com/undergroundwires/privacy.sexy/commit/52a4730073b8ebfb2ce9d530b44e4a179f5849fe)
|
||||||
|
* win: categorize and rename network security #131 | [9fd193e](https://github.com/undergroundwires/privacy.sexy/commit/9fd193e676f1f0646898f5130fbfaaf25050b2e3)
|
||||||
|
|
||||||
|
[compare](https://github.com/undergroundwires/privacy.sexy/compare/0.13.2...0.13.3)
|
||||||
|
|
||||||
## 0.13.2 (2024-04-15)
|
## 0.13.2 (2024-04-15)
|
||||||
|
|
||||||
* Update documentation for `logo-update.js` script | [4a9b430](https://github.com/undergroundwires/privacy.sexy/commit/4a9b430702bc6082426b50ecc3a06362b5720796)
|
* Update documentation for `logo-update.js` script | [4a9b430](https://github.com/undergroundwires/privacy.sexy/commit/4a9b430702bc6082426b50ecc3a06362b5720796)
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
|
- 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy).
|
||||||
- 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.2/privacy.sexy-Setup-0.13.2.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.2/privacy.sexy-0.13.2.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.2/privacy.sexy-0.13.2.AppImage). For more options, see [here](#additional-install-options).
|
- 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.3/privacy.sexy-Setup-0.13.3.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.3/privacy.sexy-0.13.3.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.13.3/privacy.sexy-0.13.3.AppImage). For more options, see [here](#additional-install-options).
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ systems or configurations that haven't undergone official testing.
|
|||||||
|
|
||||||
- **Version:** Windows 10 and later.
|
- **Version:** Windows 10 and later.
|
||||||
- **Processor:** Intel Pentium 4 or later.
|
- **Processor:** Intel Pentium 4 or later.
|
||||||
- **Architecture:** 64-bit (x64), ARM.
|
- **Architecture:** 64-bit (x86-64), ARM (ARM64).
|
||||||
|
|
||||||
> **⚠️ Compatibility Note:**
|
> **⚠️ Compatibility Note:**
|
||||||
> ARM version is only compatible with Windows 11 and later.
|
> ARM version is only compatible with Windows 11 and later.
|
||||||
@@ -17,24 +17,20 @@ systems or configurations that haven't undergone official testing.
|
|||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
- **Version:** macOS Catalina (10.15) and later.
|
- **Version:** macOS Catalina (10.15) and later.
|
||||||
- **Architecture:** Intel-based (64-bit), Apple Silicon (ARM).
|
- **Architecture:** Intel-based (x86-64), Apple silicon (ARM64).
|
||||||
|
|
||||||
> **⚠️ Compatibility Note:**
|
|
||||||
> Apple Silicon version runs non-natively, leading to slower performance due to emulation [2].
|
|
||||||
|
|
||||||
## Linux
|
## Linux
|
||||||
|
|
||||||
- **Version:** Ubuntu 18.04 and later, Fedora 32 and later, and Debian 10 and later.
|
- **Version:** Ubuntu 18.04 and later, Fedora 32 and later, and Debian 10 and later.
|
||||||
- **Processor:** Intel Pentium 4 or later.
|
- **Processor:** Intel Pentium 4 or later.
|
||||||
- **Architecture:** 64-bit (x64).
|
- **Architecture:** 64-bit (x86-64).
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
System requirements reflect Electron's platform capabilities [3] and Chromium's recommended configurations [4].
|
System requirements reflect Electron's platform capabilities [2] and Chromium's recommended configurations [3].
|
||||||
|
|
||||||
For details on the build process, see [electron-builder configuration file](./../../electron-builder.cjs).
|
For details on the build process, see [electron-builder configuration file](./../../electron-builder.cjs).
|
||||||
|
|
||||||
[1]: https://web.archive.org/web/20240428082726/https://learn.microsoft.com/en-us/windows/arm/add-arm-support#emulation-on-arm-based-devices-for-x86-or-x64-windows-apps "Add support Arm devices to your Windows app | Microsoft Learn | learn.microsoft.com"
|
[1]: https://web.archive.org/web/20240428082726/https://learn.microsoft.com/en-us/windows/arm/add-arm-support#emulation-on-arm-based-devices-for-x86-or-x64-windows-apps "Add support Arm devices to your Windows app | Microsoft Learn | learn.microsoft.com"
|
||||||
[2]: https://archive.today/2024.04.28-082901/https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary%23overview "Building a universal macOS binary | Apple Developer Documentation | developer.apple.com"
|
[2]: https://archive.ph/2024.04.28-082958/https://github.com/electron/electron/blob/main/README.md#platform-support "Platform Support | electron/README.md at main · electron/electron · GitHub | github.com"
|
||||||
[3]: https://archive.ph/2024.04.28-082958/https://github.com/electron/electron/blob/main/README.md#platform-support "Platform Support | electron/README.md at main · electron/electron · GitHub | github.com"
|
[3]: https://web.archive.org/web/20240428082945/https://support.google.com/chrome/a/answer/7100626?hl=en "Chrome browser system requirements - Chrome Enterprise and Education Help | support.google.com"
|
||||||
[4]: https://web.archive.org/web/20240428082945/https://support.google.com/chrome/a/answer/7100626?hl=en "Chrome browser system requirements - Chrome Enterprise and Education Help | support.google.com"
|
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ module.exports = {
|
|||||||
|
|
||||||
// macOS
|
// macOS
|
||||||
mac: {
|
mac: {
|
||||||
target: 'dmg',
|
target: {
|
||||||
|
target: 'dmg',
|
||||||
|
arch: 'universal',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
dmg: {
|
dmg: {
|
||||||
artifactName: '${name}-${version}.${ext}',
|
artifactName: '${name}-${version}.${ext}',
|
||||||
|
|||||||
263
package-lock.json
generated
263
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "privacy.sexy",
|
"name": "privacy.sexy",
|
||||||
"version": "0.13.2",
|
"version": "0.13.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "privacy.sexy",
|
"name": "privacy.sexy",
|
||||||
"version": "0.13.2",
|
"version": "0.13.3",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/vue": "^1.0.6",
|
"@floating-ui/vue": "^1.0.6",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"electron-updater": "^6.1.9",
|
"electron-updater": "^6.1.9",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"vue": "^3.4.21"
|
"vue": "^3.4.27"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
||||||
@@ -522,9 +522,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.24.0",
|
"version": "7.24.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
|
||||||
"integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
|
"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
},
|
},
|
||||||
@@ -3947,49 +3947,49 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
|
||||||
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
|
"integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.24.4",
|
||||||
"@vue/shared": "3.4.21",
|
"@vue/shared": "3.4.27",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
|
||||||
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
|
"integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.4.21",
|
"@vue/compiler-core": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
|
||||||
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
|
"integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.24.4",
|
||||||
"@vue/compiler-core": "3.4.21",
|
"@vue/compiler-core": "3.4.27",
|
||||||
"@vue/compiler-dom": "3.4.21",
|
"@vue/compiler-dom": "3.4.27",
|
||||||
"@vue/compiler-ssr": "3.4.21",
|
"@vue/compiler-ssr": "3.4.27",
|
||||||
"@vue/shared": "3.4.21",
|
"@vue/shared": "3.4.27",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.7",
|
"magic-string": "^0.30.10",
|
||||||
"postcss": "^8.4.35",
|
"postcss": "^8.4.38",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
|
||||||
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
|
"integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.21",
|
"@vue/compiler-dom": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/eslint-config-airbnb": {
|
"node_modules/@vue/eslint-config-airbnb": {
|
||||||
@@ -4099,48 +4099,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz",
|
||||||
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
|
"integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
|
||||||
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
|
"integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.4.21",
|
"@vue/reactivity": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
|
||||||
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
|
"integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/runtime-core": "3.4.21",
|
"@vue/runtime-core": "3.4.27",
|
||||||
"@vue/shared": "3.4.21",
|
"@vue/shared": "3.4.27",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
|
||||||
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
|
"integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.4.21",
|
"@vue/compiler-ssr": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.4.21"
|
"vue": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
|
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
|
||||||
},
|
},
|
||||||
"node_modules/@vue/test-utils": {
|
"node_modules/@vue/test-utils": {
|
||||||
"version": "2.4.5",
|
"version": "2.4.5",
|
||||||
@@ -10777,14 +10777,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.8",
|
"version": "0.30.10",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
|
||||||
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
|
"integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/map-age-cleaner": {
|
"node_modules/map-age-cleaner": {
|
||||||
@@ -16982,15 +16979,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz",
|
||||||
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
|
"integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.21",
|
"@vue/compiler-dom": "3.4.27",
|
||||||
"@vue/compiler-sfc": "3.4.21",
|
"@vue/compiler-sfc": "3.4.27",
|
||||||
"@vue/runtime-dom": "3.4.21",
|
"@vue/runtime-dom": "3.4.27",
|
||||||
"@vue/server-renderer": "3.4.21",
|
"@vue/server-renderer": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
@@ -17918,9 +17915,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.24.0",
|
"version": "7.24.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
|
||||||
"integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg=="
|
"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg=="
|
||||||
},
|
},
|
||||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
|
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
@@ -20277,49 +20274,49 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-core": {
|
"@vue/compiler-core": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
|
||||||
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
|
"integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.24.4",
|
||||||
"@vue/shared": "3.4.21",
|
"@vue/shared": "3.4.27",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-dom": {
|
"@vue/compiler-dom": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
|
||||||
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
|
"integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-core": "3.4.21",
|
"@vue/compiler-core": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-sfc": {
|
"@vue/compiler-sfc": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
|
||||||
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
|
"integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/parser": "^7.23.9",
|
"@babel/parser": "^7.24.4",
|
||||||
"@vue/compiler-core": "3.4.21",
|
"@vue/compiler-core": "3.4.27",
|
||||||
"@vue/compiler-dom": "3.4.21",
|
"@vue/compiler-dom": "3.4.27",
|
||||||
"@vue/compiler-ssr": "3.4.21",
|
"@vue/compiler-ssr": "3.4.27",
|
||||||
"@vue/shared": "3.4.21",
|
"@vue/shared": "3.4.27",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.7",
|
"magic-string": "^0.30.10",
|
||||||
"postcss": "^8.4.35",
|
"postcss": "^8.4.38",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/compiler-ssr": {
|
"@vue/compiler-ssr": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
|
||||||
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
|
"integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-dom": "3.4.21",
|
"@vue/compiler-dom": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/eslint-config-airbnb": {
|
"@vue/eslint-config-airbnb": {
|
||||||
@@ -20395,45 +20392,45 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/reactivity": {
|
"@vue/reactivity": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz",
|
||||||
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
|
"integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/runtime-core": {
|
"@vue/runtime-core": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
|
||||||
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
|
"integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/reactivity": "3.4.21",
|
"@vue/reactivity": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/runtime-dom": {
|
"@vue/runtime-dom": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
|
||||||
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
|
"integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/runtime-core": "3.4.21",
|
"@vue/runtime-core": "3.4.27",
|
||||||
"@vue/shared": "3.4.21",
|
"@vue/shared": "3.4.27",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/server-renderer": {
|
"@vue/server-renderer": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
|
||||||
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
|
"integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-ssr": "3.4.21",
|
"@vue/compiler-ssr": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/shared": {
|
"@vue/shared": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||||
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
|
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
|
||||||
},
|
},
|
||||||
"@vue/test-utils": {
|
"@vue/test-utils": {
|
||||||
"version": "2.4.5",
|
"version": "2.4.5",
|
||||||
@@ -25486,9 +25483,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"magic-string": {
|
"magic-string": {
|
||||||
"version": "0.30.8",
|
"version": "0.30.10",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
|
||||||
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
|
"integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||||
}
|
}
|
||||||
@@ -29953,15 +29950,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue": {
|
"vue": {
|
||||||
"version": "3.4.21",
|
"version": "3.4.27",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz",
|
||||||
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
|
"integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/compiler-dom": "3.4.21",
|
"@vue/compiler-dom": "3.4.27",
|
||||||
"@vue/compiler-sfc": "3.4.21",
|
"@vue/compiler-sfc": "3.4.27",
|
||||||
"@vue/runtime-dom": "3.4.21",
|
"@vue/runtime-dom": "3.4.27",
|
||||||
"@vue/server-renderer": "3.4.21",
|
"@vue/server-renderer": "3.4.27",
|
||||||
"@vue/shared": "3.4.21"
|
"@vue/shared": "3.4.27"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vue-component-type-helpers": {
|
"vue-component-type-helpers": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "privacy.sexy",
|
"name": "privacy.sexy",
|
||||||
"version": "0.13.2",
|
"version": "0.13.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"slogan": "Privacy is sexy",
|
"slogan": "Privacy is sexy",
|
||||||
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.",
|
"description": "Enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy.",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"electron-updater": "^6.1.9",
|
"electron-updater": "^6.1.9",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"vue": "^3.4.21"
|
"vue": "^3.4.27"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
||||||
|
|||||||
@@ -15,18 +15,26 @@ const DefaultOptions: ThrottleOptions = {
|
|||||||
timer: PlatformTimer,
|
timer: PlatformTimer,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function throttle(
|
export interface ThrottleFunction {
|
||||||
|
(
|
||||||
|
callback: CallbackType,
|
||||||
|
waitInMs: number,
|
||||||
|
options?: Partial<ThrottleOptions>,
|
||||||
|
): CallbackType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const throttle: ThrottleFunction = (
|
||||||
callback: CallbackType,
|
callback: CallbackType,
|
||||||
waitInMs: number,
|
waitInMs: number,
|
||||||
options: Partial<ThrottleOptions> = DefaultOptions,
|
options: Partial<ThrottleOptions> = DefaultOptions,
|
||||||
): CallbackType {
|
): CallbackType => {
|
||||||
const defaultedOptions: ThrottleOptions = {
|
const defaultedOptions: ThrottleOptions = {
|
||||||
...DefaultOptions,
|
...DefaultOptions,
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
const throttler = new Throttler(waitInMs, callback, defaultedOptions);
|
const throttler = new Throttler(waitInMs, callback, defaultedOptions);
|
||||||
return (...args: unknown[]) => throttler.invoke(...args);
|
return (...args: unknown[]) => throttler.invoke(...args);
|
||||||
}
|
};
|
||||||
|
|
||||||
class Throttler {
|
class Throttler {
|
||||||
private lastExecutionTime: number | null = null;
|
private lastExecutionTime: number | null = null;
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ function hasCall(data: FunctionData): data is CallFunctionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ensureValidFunctions(functions: readonly FunctionData[]) {
|
function ensureValidFunctions(functions: readonly FunctionData[]) {
|
||||||
|
ensureNoUnnamedFunctions(functions);
|
||||||
ensureNoDuplicatesInFunctionNames(functions);
|
ensureNoDuplicatesInFunctionNames(functions);
|
||||||
ensureEitherCallOrCodeIsDefined(functions);
|
ensureEitherCallOrCodeIsDefined(functions);
|
||||||
ensureNoDuplicateCode(functions);
|
ensureNoDuplicateCode(functions);
|
||||||
@@ -108,6 +109,16 @@ function printList(list: readonly string[]): string {
|
|||||||
return `"${list.join('","')}"`;
|
return `"${list.join('","')}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureNoUnnamedFunctions(functions: readonly FunctionData[]) {
|
||||||
|
const functionsWithoutNames = functions.filter(
|
||||||
|
(func) => !func.name || func.name.trim().length === 0,
|
||||||
|
);
|
||||||
|
if (functionsWithoutNames.length) {
|
||||||
|
const invalidFunctions = functionsWithoutNames.map((f) => JSON.stringify(f));
|
||||||
|
throw new Error(`Some function(s) have no names:\n${invalidFunctions.join('\n')}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function ensureEitherCallOrCodeIsDefined(holders: readonly FunctionData[]) {
|
function ensureEitherCallOrCodeIsDefined(holders: readonly FunctionData[]) {
|
||||||
// Ensure functions do not define both call and code
|
// Ensure functions do not define both call and code
|
||||||
const withBothCallAndCode = holders.filter((holder) => hasCode(holder) && hasCall(holder));
|
const withBothCallAndCode = holders.filter((holder) => hasCode(holder) && hasCall(holder));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="info-container">
|
<span
|
||||||
|
class="info-container"
|
||||||
|
>
|
||||||
<TooltipWrapper>
|
<TooltipWrapper>
|
||||||
<AppIcon icon="circle-info" />
|
<AppIcon icon="circle-info" />
|
||||||
<template #tooltip>
|
<template #tooltip>
|
||||||
@@ -19,27 +21,17 @@ export default defineComponent({
|
|||||||
TooltipWrapper,
|
TooltipWrapper,
|
||||||
AppIcon,
|
AppIcon,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
hasLeftMargin: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style lang="scss">
|
||||||
@use "@/presentation/assets/styles/main" as *;
|
|
||||||
|
|
||||||
@mixin apply-style-when-placed-after-non-text {
|
|
||||||
* + & {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-container {
|
.info-container {
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
|
|
||||||
* + & { // If it's followed by any other element
|
|
||||||
vertical-align: middle;
|
|
||||||
@include set-property-ch-value-with-fallback(
|
|
||||||
$property: margin-left,
|
|
||||||
$value-in-ch: 0.5,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<span class="info-tooltip-wrapper">
|
||||||
|
<span>
|
||||||
|
<slot />
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<InfoTooltipInline>
|
||||||
|
<slot name="info" />
|
||||||
|
</InfoTooltipInline>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import InfoTooltipInline from './InfoTooltipInline.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
InfoTooltipInline,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@use "@/presentation/assets/styles/main" as *;
|
||||||
|
|
||||||
|
.info-tooltip-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
@include set-property-ch-value-with-fallback(
|
||||||
|
$property: gap,
|
||||||
|
$value-in-ch: 0.5,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<p>
|
<p>
|
||||||
This requires you to do additional manual
|
This requires you to do additional manual
|
||||||
steps. If you are unsure how to follow the instructions, tap or hover on information
|
steps. If you are unsure how to follow the instructions, tap or hover on information
|
||||||
<InfoTooltip>Engage with icons like this for extra wisdom!</InfoTooltip>
|
<InfoTooltipInline>Engage with icons like this for extra wisdom!</InfoTooltipInline>
|
||||||
icons near the steps, or follow the easy alternative described above.
|
icons near the steps, or follow the easy alternative described above.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@@ -32,12 +32,12 @@ import { defineComponent, computed } from 'vue';
|
|||||||
import { injectKey } from '@/presentation/injectionSymbols';
|
import { injectKey } from '@/presentation/injectionSymbols';
|
||||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||||
import { getOperatingSystemDisplayName } from '@/presentation/components/Shared/OperatingSystemNames';
|
import { getOperatingSystemDisplayName } from '@/presentation/components/Shared/OperatingSystemNames';
|
||||||
import InfoTooltip from './InfoTooltip.vue';
|
import InfoTooltipInline from './Help/InfoTooltipInline.vue';
|
||||||
import PlatformInstructionSteps from './Steps/PlatformInstructionSteps.vue';
|
import PlatformInstructionSteps from './Steps/PlatformInstructionSteps.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
InfoTooltip,
|
InfoTooltipInline,
|
||||||
PlatformInstructionSteps,
|
PlatformInstructionSteps,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<InstructionSteps>
|
<InstructionSteps>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
Download the file.
|
Download the file.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
You should have already been prompted to save the script file.
|
You should have already been prompted to save the script file.
|
||||||
</p>
|
</p>
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
If this was not the case or you did not save the script when prompted,
|
If this was not the case or you did not save the script when prompted,
|
||||||
please try to download your script file again.
|
please try to download your script file again.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
Open terminal.
|
Open terminal.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
Opening terminal changes based on the distro you run.
|
Opening terminal changes based on the distro you run.
|
||||||
</p>
|
</p>
|
||||||
@@ -39,30 +39,32 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
<p>
|
<p>
|
||||||
Navigate to the folder where you downloaded the file e.g.:
|
Navigate to the folder where you downloaded the file e.g.:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<CopyableCommand>cd ~/Downloads</CopyableCommand>
|
<InfoTooltipWrapper>
|
||||||
<InfoTooltip>
|
<CopyableCommand>cd ~/Downloads</CopyableCommand>
|
||||||
<p>
|
<template #info>
|
||||||
Press on <code>enter/return</code> key after running the command.
|
<p>
|
||||||
</p>
|
Press on <code>enter/return</code> key after running the command.
|
||||||
<p>
|
</p>
|
||||||
If the file is not downloaded on Downloads folder,
|
<p>
|
||||||
change <code>Downloads</code> to path where the file is downloaded.
|
If the file is not downloaded on Downloads folder,
|
||||||
</p>
|
change <code>Downloads</code> to path where the file is downloaded.
|
||||||
<p>
|
</p>
|
||||||
This command means:
|
<p>
|
||||||
<ul>
|
This command means:
|
||||||
<li><code>cd</code> will change the current folder.</li>
|
<ul>
|
||||||
<li><code>~</code> is the user home directory.</li>
|
<li><code>cd</code> will change the current folder.</li>
|
||||||
</ul>
|
<li><code>~</code> is the user home directory.</li>
|
||||||
</p>
|
</ul>
|
||||||
</InfoTooltip>
|
</p>
|
||||||
|
</template>
|
||||||
|
</InfoTooltipWrapper>
|
||||||
</p>
|
</p>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
@@ -70,26 +72,28 @@
|
|||||||
Give the file execute permissions:
|
Give the file execute permissions:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<CopyableCommand>chmod +x {{ filename }}</CopyableCommand>
|
<InfoTooltipWrapper>
|
||||||
<InfoTooltip>
|
<CopyableCommand>chmod +x {{ filename }}</CopyableCommand>
|
||||||
<p>
|
<template #info>
|
||||||
Press on <code>enter/return</code> key after running the command.
|
<p>
|
||||||
</p>
|
Press on <code>enter/return</code> key after running the command.
|
||||||
<p>
|
</p>
|
||||||
It will make the file executable.
|
<p>
|
||||||
</p>
|
It will make the file executable.
|
||||||
<p>
|
</p>
|
||||||
If you use desktop environment you can alternatively (instead of running the command):
|
<p>
|
||||||
<ol>
|
If you use desktop environment you can alternatively (instead of running the command):
|
||||||
<li>Locate the file using your file manager.</li>
|
<ol>
|
||||||
<li>Right click on the file, select "Properties".</li>
|
<li>Locate the file using your file manager.</li>
|
||||||
<li>Go to "Permissions" and check "Allow executing file as program".</li>
|
<li>Right click on the file, select "Properties".</li>
|
||||||
</ol>
|
<li>Go to "Permissions" and check "Allow executing file as program".</li>
|
||||||
</p>
|
</ol>
|
||||||
<p>
|
</p>
|
||||||
These GUI steps and name of options may change depending on your file manager.'
|
<p>
|
||||||
</p>
|
These GUI steps and name of options may change depending on your file manager.'
|
||||||
</InfoTooltip>
|
</p>
|
||||||
|
</template>
|
||||||
|
</InfoTooltipWrapper>
|
||||||
</p>
|
</p>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
@@ -97,21 +101,24 @@
|
|||||||
Execute the file:
|
Execute the file:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<CopyableCommand>./{{ filename }}</CopyableCommand>
|
<InfoTooltipWrapper>
|
||||||
<InfoTooltip>
|
<CopyableCommand>./{{ filename }}</CopyableCommand>
|
||||||
<p>
|
<template #info>
|
||||||
If you have desktop environment, instead of running this command you can alternatively:
|
<p>
|
||||||
</p>
|
If you have desktop environment, instead of running this command
|
||||||
<ol>
|
you can alternatively:
|
||||||
<li>Locate the file using your file manager.</li>
|
</p>
|
||||||
<li>Right click on the file, select "Run as program".</li>
|
<ol>
|
||||||
</ol>
|
<li>Locate the file using your file manager.</li>
|
||||||
</InfoTooltip>
|
<li>Right click on the file, select "Run as program".</li>
|
||||||
|
</ol>
|
||||||
|
</template>
|
||||||
|
</InfoTooltipWrapper>
|
||||||
</p>
|
</p>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
If asked, enter your administrator password.
|
If asked, enter your administrator password.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
As you type, your password will be hidden but the keys are still
|
As you type, your password will be hidden but the keys are still
|
||||||
registered, so keep typing.
|
registered, so keep typing.
|
||||||
@@ -122,7 +129,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Administrator privileges are required to configure OS.
|
Administrator privileges are required to configure OS.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
</InstructionSteps>
|
</InstructionSteps>
|
||||||
</template>
|
</template>
|
||||||
@@ -131,13 +138,15 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import InstructionSteps from '../InstructionSteps.vue';
|
import InstructionSteps from '../InstructionSteps.vue';
|
||||||
import InstructionStep from '../InstructionStep.vue';
|
import InstructionStep from '../InstructionStep.vue';
|
||||||
import InfoTooltip from '../../InfoTooltip.vue';
|
import InfoTooltipInline from '../../Help/InfoTooltipInline.vue';
|
||||||
|
import InfoTooltipWrapper from '../../Help/InfoTooltipWrapper.vue';
|
||||||
import CopyableCommand from '../CopyableCommand.vue';
|
import CopyableCommand from '../CopyableCommand.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
CopyableCommand,
|
CopyableCommand,
|
||||||
InfoTooltip,
|
InfoTooltipInline,
|
||||||
|
InfoTooltipWrapper,
|
||||||
InstructionSteps,
|
InstructionSteps,
|
||||||
InstructionStep,
|
InstructionStep,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<InstructionSteps>
|
<InstructionSteps>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
Download the file.
|
Download the file.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
You should have already been prompted to save the script file.
|
You should have already been prompted to save the script file.
|
||||||
</p>
|
</p>
|
||||||
@@ -10,38 +10,38 @@
|
|||||||
If this was not the case or you did not save the script when prompted,
|
If this was not the case or you did not save the script when prompted,
|
||||||
please try to download your script file again.
|
please try to download your script file again.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
Open terminal.
|
Open terminal.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
Type Terminal into Spotlight or open it from the Applications -> Utilities folder.
|
Type Terminal into Spotlight or open it from the Applications -> Utilities folder.
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
<p>
|
<p>
|
||||||
Navigate to the folder where you downloaded the file e.g.:
|
Navigate to the folder where you downloaded the file e.g.:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<CopyableCommand>
|
<InfoTooltipWrapper>
|
||||||
cd ~/Downloads
|
<CopyableCommand>cd ~/Downloads</CopyableCommand>
|
||||||
</CopyableCommand>
|
<template #info>
|
||||||
<InfoTooltip>
|
<p>
|
||||||
<p>
|
Press on <code>enter/return</code> key after running the command.
|
||||||
Press on <code>enter/return</code> key after running the command.
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
If the file is not downloaded on Downloads folder,
|
||||||
If the file is not downloaded on Downloads folder,
|
change <code>Downloads</code> to path where the file is downloaded.
|
||||||
change <code>Downloads</code> to path where the file is downloaded.
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
This command means:
|
||||||
This command means:
|
<ul>
|
||||||
<ul>
|
<li><code>cd</code> will change the current folder.</li>
|
||||||
<li><code>cd</code> will change the current folder.</li>
|
<li><code>~</code> is the user home directory.</li>
|
||||||
<li><code>~</code> is the user home directory.</li>
|
</ul>
|
||||||
</ul>
|
</p>
|
||||||
</p>
|
</template>
|
||||||
</InfoTooltip>
|
</InfoTooltipWrapper>
|
||||||
</p>
|
</p>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
@@ -49,15 +49,17 @@
|
|||||||
Give the file execute permissions:
|
Give the file execute permissions:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<CopyableCommand>chmod +x {{ filename }}</CopyableCommand>
|
<InfoTooltipWrapper>
|
||||||
<InfoTooltip>
|
<CopyableCommand>chmod +x {{ filename }}</CopyableCommand>
|
||||||
<p>
|
<template #info>
|
||||||
Press on <code>enter/return</code> key after running the command.
|
<p>
|
||||||
</p>
|
Press on <code>enter/return</code> key after running the command.
|
||||||
<p>
|
</p>
|
||||||
It will make the file executable.
|
<p>
|
||||||
</p>
|
It will make the file executable.
|
||||||
</InfoTooltip>
|
</p>
|
||||||
|
</template>
|
||||||
|
</InfoTooltipWrapper>
|
||||||
</p>
|
</p>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
@@ -65,15 +67,17 @@
|
|||||||
Execute the file:
|
Execute the file:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<CopyableCommand>./{{ filename }}</CopyableCommand>
|
<InfoTooltipWrapper>
|
||||||
<InfoTooltip>
|
<CopyableCommand>./{{ filename }}</CopyableCommand>
|
||||||
Alternatively you can locate the file in <strong>Finder</strong> and double click on it.
|
<template #info>
|
||||||
</InfoTooltip>
|
Alternatively you can locate the file in <strong>Finder</strong> and double click on it.
|
||||||
|
</template>
|
||||||
|
</InfoTooltipWrapper>
|
||||||
</p>
|
</p>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
If asked, enter your administrator password.
|
If asked, enter your administrator password.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
As you type, your password will be hidden but the keys are
|
As you type, your password will be hidden but the keys are
|
||||||
still registered, so keep typing.
|
still registered, so keep typing.
|
||||||
@@ -84,7 +88,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Administrator privileges are required to configure OS.
|
Administrator privileges are required to configure OS.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
</InstructionSteps>
|
</InstructionSteps>
|
||||||
</template>
|
</template>
|
||||||
@@ -93,13 +97,15 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import InstructionSteps from '../InstructionSteps.vue';
|
import InstructionSteps from '../InstructionSteps.vue';
|
||||||
import InstructionStep from '../InstructionStep.vue';
|
import InstructionStep from '../InstructionStep.vue';
|
||||||
import InfoTooltip from '../../InfoTooltip.vue';
|
import InfoTooltipInline from '../../Help/InfoTooltipInline.vue';
|
||||||
|
import InfoTooltipWrapper from '../../Help/InfoTooltipWrapper.vue';
|
||||||
import CopyableCommand from '../CopyableCommand.vue';
|
import CopyableCommand from '../CopyableCommand.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
CopyableCommand,
|
CopyableCommand,
|
||||||
InfoTooltip,
|
InfoTooltipInline,
|
||||||
|
InfoTooltipWrapper,
|
||||||
InstructionSteps,
|
InstructionSteps,
|
||||||
InstructionStep,
|
InstructionStep,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
<InstructionSteps>
|
<InstructionSteps>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
Download the file.
|
Download the file.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>If a save prompt doesn't appear, try downloading the script again.</p>
|
<p>If a save prompt doesn't appear, try downloading the script again.</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
If warned by your browser, keep the file.
|
If warned by your browser, keep the file.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<!--
|
<!--
|
||||||
Tests (15/01/2023):
|
Tests (15/01/2023):
|
||||||
- Edge (Defender activated): "filename isn't commonly downloaded..."
|
- Edge (Defender activated): "filename isn't commonly downloaded..."
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
For <strong>Firefox</strong> and <strong>Chrome</strong>, typically no additional
|
For <strong>Firefox</strong> and <strong>Chrome</strong>, typically no additional
|
||||||
action is needed.
|
action is needed.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
If your antivirus (e.g., Defender) alerts you, address the warning.
|
If your antivirus (e.g., Defender) alerts you, address the warning.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<!--
|
<!--
|
||||||
Tests (15/01/2023):
|
Tests (15/01/2023):
|
||||||
- Edge (Defender activated): "Couldn't download - Virus detected"
|
- Edge (Defender activated): "Couldn't download - Virus detected"
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
<li>and keep real-time protection enabled whenever possible.</li>
|
<li>and keep real-time protection enabled whenever possible.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
<!--
|
<!--
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
- Firefox: "filename is executable file. Executable files may contain..?" OK/Cancel
|
- Firefox: "filename is executable file. Executable files may contain..?" OK/Cancel
|
||||||
-->
|
-->
|
||||||
Open the downloaded file.
|
Open the downloaded file.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
Confirm any browser prompts to open the file.
|
Confirm any browser prompts to open the file.
|
||||||
</p>
|
</p>
|
||||||
@@ -100,11 +100,11 @@
|
|||||||
<strong>Edge</strong> and <strong>Chrome</strong> users usually will not
|
<strong>Edge</strong> and <strong>Chrome</strong> users usually will not
|
||||||
encounter additional prompts.
|
encounter additional prompts.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
If prompted, confirm SmartScreen warnings.
|
If prompted, confirm SmartScreen warnings.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
Windows SmartScreen might display a cautionary message.
|
Windows SmartScreen might display a cautionary message.
|
||||||
</p>
|
</p>
|
||||||
@@ -118,11 +118,11 @@
|
|||||||
<li>Select <strong>Run anyway</strong>.</li>
|
<li>Select <strong>Run anyway</strong>.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
<InstructionStep>
|
<InstructionStep>
|
||||||
If administrative permissions are requested, grant them.
|
If administrative permissions are requested, grant them.
|
||||||
<InfoTooltip>
|
<InfoTooltipInline>
|
||||||
<p>
|
<p>
|
||||||
The script may request administrative rights to apply changes.
|
The script may request administrative rights to apply changes.
|
||||||
</p>
|
</p>
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Click <strong>Yes</strong> to authorize and run the script.
|
Click <strong>Yes</strong> to authorize and run the script.
|
||||||
</p>
|
</p>
|
||||||
</InfoTooltip>
|
</InfoTooltipInline>
|
||||||
</InstructionStep>
|
</InstructionStep>
|
||||||
</InstructionSteps>
|
</InstructionSteps>
|
||||||
</template>
|
</template>
|
||||||
@@ -141,11 +141,11 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import InstructionSteps from '../InstructionSteps.vue';
|
import InstructionSteps from '../InstructionSteps.vue';
|
||||||
import InstructionStep from '../InstructionStep.vue';
|
import InstructionStep from '../InstructionStep.vue';
|
||||||
import InfoTooltip from '../../InfoTooltip.vue';
|
import InfoTooltipInline from '../../Help/InfoTooltipInline.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
InfoTooltip,
|
InfoTooltipInline,
|
||||||
InstructionSteps,
|
InstructionSteps,
|
||||||
InstructionStep,
|
InstructionStep,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
computed, readonly, ref, watch,
|
computed, readonly, ref, shallowRef, watch,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { throttle } from '@/application/Common/Timing/Throttle';
|
import { throttle } from '@/application/Common/Timing/Throttle';
|
||||||
import { useAutoUnsubscribedEventListener } from '../Shared/Hooks/UseAutoUnsubscribedEventListener';
|
import { useAutoUnsubscribedEventListener } from '../Shared/Hooks/UseAutoUnsubscribedEventListener';
|
||||||
|
import { useResizeObserver } from '../Shared/Hooks/Resize/UseResizeObserver';
|
||||||
|
|
||||||
const RESIZE_EVENT_THROTTLE_MS = 200;
|
const RESIZE_EVENT_THROTTLE_MS = 200;
|
||||||
|
|
||||||
@@ -29,11 +30,17 @@ function getScrollbarGutterWidth(): number {
|
|||||||
|
|
||||||
function useBodyWidth() {
|
function useBodyWidth() {
|
||||||
const width = ref(document.body.offsetWidth);
|
const width = ref(document.body.offsetWidth);
|
||||||
const observer = new ResizeObserver((entries) => throttle(() => {
|
useResizeObserver(
|
||||||
for (const entry of entries) {
|
{
|
||||||
width.value = entry.borderBoxSize[0].inlineSize;
|
observedElementRef: shallowRef(document.body),
|
||||||
}
|
throttleInMs: RESIZE_EVENT_THROTTLE_MS,
|
||||||
}, RESIZE_EVENT_THROTTLE_MS));
|
observeCallback: (entries) => {
|
||||||
observer.observe(document.body, { box: 'border-box' });
|
for (const entry of entries) {
|
||||||
|
width.value = entry.borderBoxSize[0].inlineSize;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
observeOptions: { box: 'border-box' },
|
||||||
|
},
|
||||||
|
);
|
||||||
return readonly(width);
|
return readonly(width);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,9 +68,7 @@ export default defineComponent({
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1; // Expands the container to fill available horizontal space, enabling alignment of child items.
|
flex: 1; // Expands the container to fill available horizontal space, enabling alignment of child items.
|
||||||
max-width: 100%; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
|
max-width: 100%; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
|
||||||
*:not(:first-child) {
|
|
||||||
margin-left: $spacing-absolute-small;
|
|
||||||
}
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -80,6 +78,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
.docs {
|
.docs {
|
||||||
background: $color-primary-darkest;
|
background: $color-primary-darkest;
|
||||||
|
margin-left: $spacing-absolute-small;
|
||||||
margin-top: $spacing-relative-x-small;
|
margin-top: $spacing-relative-x-small;
|
||||||
color: $color-on-primary;
|
color: $color-on-primary;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { onBeforeUnmount } from 'vue';
|
||||||
|
|
||||||
|
export function useAnimationFrameLimiter(
|
||||||
|
cancelAnimationFrame: CancelAnimationFrameFunction = window.cancelAnimationFrame,
|
||||||
|
requestAnimationFrame: RequestAnimationFrameFunction = window.requestAnimationFrame,
|
||||||
|
onTeardown: RegisterTeardownCallbackFunction = onBeforeUnmount,
|
||||||
|
): AnimationFrameLimiter {
|
||||||
|
let requestId: AnimationFrameId | null = null;
|
||||||
|
const cancelNextFrame = () => {
|
||||||
|
if (requestId === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cancelAnimationFrame(requestId);
|
||||||
|
};
|
||||||
|
const resetNextFrame = (callback: AnimationFrameRequestCallback) => {
|
||||||
|
cancelNextFrame();
|
||||||
|
requestId = requestAnimationFrame(callback);
|
||||||
|
};
|
||||||
|
onTeardown(() => {
|
||||||
|
cancelNextFrame();
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
cancelNextFrame,
|
||||||
|
resetNextFrame,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CancelAnimationFrameFunction = typeof window.cancelAnimationFrame;
|
||||||
|
|
||||||
|
export type RequestAnimationFrameFunction = (callback: AnimationFrameRequestCallback) => number;
|
||||||
|
|
||||||
|
export type RegisterTeardownCallbackFunction = (callback: () => void) => void;
|
||||||
|
|
||||||
|
export type AnimationFrameId = ReturnType<typeof requestAnimationFrame>;
|
||||||
|
|
||||||
|
export type AnimationFrameRequestCallback = () => void;
|
||||||
|
|
||||||
|
export interface AnimationFrameLimiter {
|
||||||
|
cancelNextFrame(): void;
|
||||||
|
resetNextFrame(callback: AnimationFrameRequestCallback): void;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import {
|
||||||
|
onBeforeMount, onBeforeUnmount,
|
||||||
|
watch, type Ref,
|
||||||
|
} from 'vue';
|
||||||
|
import { throttle, type ThrottleFunction } from '@/application/Common/Timing/Throttle';
|
||||||
|
import { useResizeObserverPolyfill } from './UseResizeObserverPolyfill';
|
||||||
|
import { useAnimationFrameLimiter } from './UseAnimationFrameLimiter';
|
||||||
|
|
||||||
|
export function useResizeObserver(
|
||||||
|
config: ResizeObserverConfig,
|
||||||
|
usePolyfill = useResizeObserverPolyfill,
|
||||||
|
useFrameLimiter = useAnimationFrameLimiter,
|
||||||
|
throttler: ThrottleFunction = throttle,
|
||||||
|
onSetup: LifecycleHookRegistration = onBeforeMount,
|
||||||
|
onTeardown: LifecycleHookRegistration = onBeforeUnmount,
|
||||||
|
) {
|
||||||
|
const { resetNextFrame, cancelNextFrame } = useFrameLimiter();
|
||||||
|
// This prevents the 'ResizeObserver loop completed with undelivered notifications' error when
|
||||||
|
// the browser can't process all observations within one animation frame.
|
||||||
|
// Reference: https://github.com/WICG/resize-observer/issues/38
|
||||||
|
|
||||||
|
const { resizeObserverReady } = usePolyfill();
|
||||||
|
// This ensures compatibility with ancient browsers. All modern browsers support ResizeObserver.
|
||||||
|
// Compatibility info: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#browser_compatibility
|
||||||
|
|
||||||
|
const throttledCallback = throttler(config.observeCallback, config.throttleInMs);
|
||||||
|
// Throttling enhances performance during rapid changes such as window resizing.
|
||||||
|
|
||||||
|
let observer: ResizeObserver | null;
|
||||||
|
|
||||||
|
const disposeObserver = () => {
|
||||||
|
cancelNextFrame();
|
||||||
|
observer?.disconnect();
|
||||||
|
observer = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
onSetup(() => {
|
||||||
|
watch(() => config.observedElementRef.value, (element) => {
|
||||||
|
if (!element) {
|
||||||
|
disposeObserver();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resizeObserverReady.then((createObserver) => {
|
||||||
|
disposeObserver();
|
||||||
|
observer = createObserver((...args) => {
|
||||||
|
resetNextFrame(() => throttledCallback(...args));
|
||||||
|
});
|
||||||
|
observer.observe(element, config?.observeOptions);
|
||||||
|
});
|
||||||
|
}, { immediate: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
onTeardown(() => {
|
||||||
|
disposeObserver();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResizeObserverConfig {
|
||||||
|
readonly observedElementRef: ObservedElementReference;
|
||||||
|
readonly throttleInMs: number;
|
||||||
|
readonly observeCallback: ResizeObserverCallback;
|
||||||
|
readonly observeOptions?: ResizeObserverOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ObservedElementReference = Readonly<Ref<HTMLElement | undefined>>;
|
||||||
|
|
||||||
|
export type LifecycleHookRegistration = (callback: () => void) => void;
|
||||||
@@ -16,11 +16,17 @@ async function polyfillResizeObserver(): Promise<typeof ResizeObserver> {
|
|||||||
return polyfillLoader.getValue();
|
return polyfillLoader.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ResizeObserverCreator {
|
||||||
|
(
|
||||||
|
...args: ConstructorParameters<typeof ResizeObserver>
|
||||||
|
): ResizeObserver;
|
||||||
|
}
|
||||||
|
|
||||||
export function useResizeObserverPolyfill() {
|
export function useResizeObserverPolyfill() {
|
||||||
const resizeObserverReady = new Promise<void>((resolve) => {
|
const resizeObserverReady = new Promise<ResizeObserverCreator>((resolve) => {
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await polyfillResizeObserver();
|
await polyfillResizeObserver();
|
||||||
resolve();
|
resolve((args) => new ResizeObserver(args));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return { resizeObserverReady };
|
return { resizeObserverReady };
|
||||||
@@ -6,10 +6,9 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
defineComponent, shallowRef, onMounted, onBeforeUnmount, watch,
|
defineComponent, shallowRef, onMounted, watch,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/UseResizeObserverPolyfill';
|
import { useResizeObserver } from './Hooks/Resize/UseResizeObserver';
|
||||||
import { throttle } from '@/application/Common/Timing/Throttle';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
emits: {
|
emits: {
|
||||||
@@ -20,31 +19,21 @@ export default defineComponent({
|
|||||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||||
},
|
},
|
||||||
setup(_, { emit }) {
|
setup(_, { emit }) {
|
||||||
const { resizeObserverReady } = useResizeObserverPolyfill();
|
|
||||||
|
|
||||||
const containerElement = shallowRef<HTMLElement>();
|
const containerElement = shallowRef<HTMLElement>();
|
||||||
|
|
||||||
let width = 0;
|
let width = 0;
|
||||||
let height = 0;
|
let height = 0;
|
||||||
let observer: ResizeObserver | undefined;
|
|
||||||
|
|
||||||
onMounted(() => {
|
useResizeObserver({
|
||||||
watch(() => containerElement.value, async (element) => {
|
observedElementRef: containerElement,
|
||||||
if (!element) {
|
observeCallback: updateSize,
|
||||||
disposeObserver();
|
throttleInMs: 200,
|
||||||
return;
|
|
||||||
}
|
|
||||||
resizeObserverReady.then(() => {
|
|
||||||
disposeObserver();
|
|
||||||
observer = new ResizeObserver(throttle(updateSize, 200));
|
|
||||||
observer.observe(element);
|
|
||||||
});
|
|
||||||
updateSize(); // Do not throttle, immediately inform new width
|
|
||||||
}, { immediate: true });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onMounted(() => {
|
||||||
disposeObserver();
|
watch(() => containerElement.value, async () => {
|
||||||
|
updateSize();
|
||||||
|
}, { immediate: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateSize() {
|
function updateSize() {
|
||||||
@@ -81,11 +70,6 @@ export default defineComponent({
|
|||||||
return { isChanged: true };
|
return { isChanged: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
function disposeObserver() {
|
|
||||||
observer?.disconnect();
|
|
||||||
observer = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
containerElement,
|
containerElement,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import {
|
|||||||
useFloating, arrow, shift, flip, type Placement, offset, type Side, type Coords, autoUpdate,
|
useFloating, arrow, shift, flip, type Placement, offset, type Side, type Coords, autoUpdate,
|
||||||
} from '@floating-ui/vue';
|
} from '@floating-ui/vue';
|
||||||
import { defineComponent, shallowRef, computed } from 'vue';
|
import { defineComponent, shallowRef, computed } from 'vue';
|
||||||
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/UseResizeObserverPolyfill';
|
import { useResizeObserverPolyfill } from '@/presentation/components/Shared/Hooks/Resize/UseResizeObserverPolyfill';
|
||||||
import { throttle } from '@/application/Common/Timing/Throttle';
|
import { throttle } from '@/application/Common/Timing/Throttle';
|
||||||
import { type TargetEventListener } from '@/presentation/components/Shared/Hooks/UseAutoUnsubscribedEventListener';
|
import { type TargetEventListener } from '@/presentation/components/Shared/Hooks/UseAutoUnsubscribedEventListener';
|
||||||
import { injectKey } from '@/presentation/injectionSymbols';
|
import { injectKey } from '@/presentation/injectionSymbols';
|
||||||
|
|||||||
@@ -105,5 +105,5 @@ console.log(`Status code: ${status.code}`);
|
|||||||
- This is useful for websites that do not respond to HEAD requests, such as those behind certain CDN or web application firewalls.
|
- This is useful for websites that do not respond to HEAD requests, such as those behind certain CDN or web application firewalls.
|
||||||
- Provide patterns as regular expressions (`RegExp`), allowing them to match any part of a URL.
|
- Provide patterns as regular expressions (`RegExp`), allowing them to match any part of a URL.
|
||||||
- Examples:
|
- Examples:
|
||||||
- To match any URL starting with "https://example.com/api": `/^https:\/\/example\.com\/api/`
|
- To match any URL starting with `https://example.com/api`: `/^https:\/\/example\.com\/api/`
|
||||||
- To match any domain ending with "cloudflare.com": `/^https:\/\/.*\.cloudflare\.com\//`
|
- To match any domain ending with `cloudflare.com`: `/^https:\/\/.*\.cloudflare\.com\//`
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ describe('revert toggle', () => {
|
|||||||
cardIndex: 1, // first is often cleanup that may lack revert button
|
cardIndex: 1, // first is often cleanup that may lack revert button
|
||||||
});
|
});
|
||||||
cy.get('.toggle-switch')
|
cy.get('.toggle-switch')
|
||||||
|
.filter(':visible') // Avoid side-effects from hidden cards
|
||||||
.first()
|
.first()
|
||||||
.as('toggleSwitch');
|
.as('toggleSwitch');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { TimerStub } from '@tests/unit/shared/Stubs/TimerStub';
|
import { TimerStub } from '@tests/unit/shared/Stubs/TimerStub';
|
||||||
import { throttle, type ThrottleOptions } from '@/application/Common/Timing/Throttle';
|
import { throttle, type ThrottleFunction, type ThrottleOptions } from '@/application/Common/Timing/Throttle';
|
||||||
import type { Timer } from '@/application/Common/Timing/Timer';
|
import type { Timer } from '@/application/Common/Timing/Timer';
|
||||||
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
|
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ describe('throttle', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
type CallbackType = Parameters<typeof throttle>[0];
|
type CallbackType = Parameters<ThrottleFunction>[0];
|
||||||
|
|
||||||
class TestContext {
|
class TestContext {
|
||||||
private options: Partial<ThrottleOptions> | undefined = {
|
private options: Partial<ThrottleOptions> | undefined = {
|
||||||
@@ -315,7 +315,7 @@ class TestContext {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public throttle(): ReturnType<typeof throttle> {
|
public throttle(): ReturnType<ThrottleFunction> {
|
||||||
return throttle(
|
return throttle(
|
||||||
this.callback,
|
this.callback,
|
||||||
this.waitInMs,
|
this.waitInMs,
|
||||||
|
|||||||
@@ -26,6 +26,27 @@ describe('SharedFunctionsParser', () => {
|
|||||||
});
|
});
|
||||||
describe('parseFunctions', () => {
|
describe('parseFunctions', () => {
|
||||||
describe('validates functions', () => {
|
describe('validates functions', () => {
|
||||||
|
it('throws when functions have no names', () => {
|
||||||
|
// arrange
|
||||||
|
const invalidFunctions = [
|
||||||
|
createFunctionDataWithCode()
|
||||||
|
.withCode('test function 1')
|
||||||
|
.withName(' '), // Whitespace,
|
||||||
|
createFunctionDataWithCode()
|
||||||
|
.withCode('test function 2')
|
||||||
|
.withName(undefined as unknown as string), // Undefined
|
||||||
|
createFunctionDataWithCode()
|
||||||
|
.withCode('test function 3')
|
||||||
|
.withName(''), // Empty
|
||||||
|
];
|
||||||
|
const expectedError = `Some function(s) have no names:\n${invalidFunctions.map((f) => JSON.stringify(f)).join('\n')}`;
|
||||||
|
// act
|
||||||
|
const act = () => new ParseFunctionsCallerWithDefaults()
|
||||||
|
.withFunctions(invalidFunctions)
|
||||||
|
.parseFunctions();
|
||||||
|
// assert
|
||||||
|
expect(act).to.throw(expectedError);
|
||||||
|
});
|
||||||
it('throws when functions have same names', () => {
|
it('throws when functions have same names', () => {
|
||||||
// arrange
|
// arrange
|
||||||
const name = 'same-func-name';
|
const name = 'same-func-name';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
|
|||||||
import { ref, type Ref } from 'vue';
|
import { ref, type Ref } from 'vue';
|
||||||
import { useDragHandler, type DragDomModifier } from '@/presentation/components/Scripts/Slider/UseDragHandler';
|
import { useDragHandler, type DragDomModifier } from '@/presentation/components/Scripts/Slider/UseDragHandler';
|
||||||
import { ThrottleStub } from '@tests/unit/shared/Stubs/ThrottleStub';
|
import { ThrottleStub } from '@tests/unit/shared/Stubs/ThrottleStub';
|
||||||
import { throttle } from '@/application/Common/Timing/Throttle';
|
import { type ThrottleFunction } from '@/application/Common/Timing/Throttle';
|
||||||
import type { ConstructorArguments } from '@/TypeHelpers';
|
import type { ConstructorArguments } from '@/TypeHelpers';
|
||||||
|
|
||||||
describe('useDragHandler', () => {
|
describe('useDragHandler', () => {
|
||||||
@@ -235,7 +235,7 @@ describe('useDragHandler', () => {
|
|||||||
function initializeDragHandlerWithMocks(mocks?: {
|
function initializeDragHandlerWithMocks(mocks?: {
|
||||||
readonly dragDomModifier?: DragDomModifier;
|
readonly dragDomModifier?: DragDomModifier;
|
||||||
readonly draggableElementRef?: Ref<HTMLElement>;
|
readonly draggableElementRef?: Ref<HTMLElement>;
|
||||||
readonly throttler?: typeof throttle,
|
readonly throttler?: ThrottleFunction,
|
||||||
}) {
|
}) {
|
||||||
return useDragHandler(
|
return useDragHandler(
|
||||||
mocks?.draggableElementRef ?? ref(document.createElement('div')),
|
mocks?.draggableElementRef ?? ref(document.createElement('div')),
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import {
|
||||||
|
useAnimationFrameLimiter, type AnimationFrameId, type AnimationFrameRequestCallback,
|
||||||
|
type CancelAnimationFrameFunction, type RegisterTeardownCallbackFunction,
|
||||||
|
type RequestAnimationFrameFunction,
|
||||||
|
} from '@/presentation/components/Shared/Hooks/Resize/UseAnimationFrameLimiter';
|
||||||
|
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
|
||||||
|
|
||||||
|
describe('useAnimationFrameLimiter', () => {
|
||||||
|
describe('resetNextFrame', () => {
|
||||||
|
it('schedules the callback in the next animation frame', () => {
|
||||||
|
// arrange
|
||||||
|
const expectedCallback = () => {};
|
||||||
|
let scheduledCallback: AnimationFrameRequestCallback | undefined;
|
||||||
|
const requestAnimationFrame: RequestAnimationFrameFunction = (callback) => {
|
||||||
|
scheduledCallback = callback;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
const context = new TestContext()
|
||||||
|
.withRequestAnimationFrameFunction(requestAnimationFrame);
|
||||||
|
// act
|
||||||
|
const { resetNextFrame } = context.useAnimationFrameLimiter();
|
||||||
|
resetNextFrame(expectedCallback);
|
||||||
|
// assert
|
||||||
|
expect(scheduledCallback).to.equal(expectedCallback);
|
||||||
|
});
|
||||||
|
it('cancels the existing animation frame before scheduling a new one', () => {
|
||||||
|
// arrange
|
||||||
|
const expectedCancelledAnimationFrameId: AnimationFrameId = 5;
|
||||||
|
let actualCancelledAnimationFrameId: AnimationFrameId | undefined;
|
||||||
|
const requestAnimationFrame: RequestAnimationFrameFunction = () => {
|
||||||
|
return expectedCancelledAnimationFrameId;
|
||||||
|
};
|
||||||
|
const cancelAnimationFrame: CancelAnimationFrameFunction = (animationFrameId) => {
|
||||||
|
actualCancelledAnimationFrameId = animationFrameId;
|
||||||
|
};
|
||||||
|
const context = new TestContext()
|
||||||
|
.withRequestAnimationFrameFunction(requestAnimationFrame)
|
||||||
|
.withCancelAnimationFrame(cancelAnimationFrame);
|
||||||
|
// act
|
||||||
|
const { resetNextFrame } = context.useAnimationFrameLimiter();
|
||||||
|
resetNextFrame(() => {}); // Nothing to cancel in first call
|
||||||
|
resetNextFrame(() => {});
|
||||||
|
// assert
|
||||||
|
expect(actualCancelledAnimationFrameId).to.equal(expectedCancelledAnimationFrameId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('cancelNextFrame', () => {
|
||||||
|
it('cancels the scheduled animation frame if one exists', () => {
|
||||||
|
// arrange
|
||||||
|
const expectedCancelledAnimationFrameId: AnimationFrameId = 5;
|
||||||
|
let actualCancelledAnimationFrameId: AnimationFrameId | undefined;
|
||||||
|
const requestAnimationFrame: RequestAnimationFrameFunction = () => {
|
||||||
|
return expectedCancelledAnimationFrameId;
|
||||||
|
};
|
||||||
|
const cancelAnimationFrame: CancelAnimationFrameFunction = (animationFrameId) => {
|
||||||
|
actualCancelledAnimationFrameId = animationFrameId;
|
||||||
|
};
|
||||||
|
const context = new TestContext()
|
||||||
|
.withRequestAnimationFrameFunction(requestAnimationFrame)
|
||||||
|
.withCancelAnimationFrame(cancelAnimationFrame);
|
||||||
|
// act
|
||||||
|
const { resetNextFrame, cancelNextFrame } = context.useAnimationFrameLimiter();
|
||||||
|
resetNextFrame(() => {}); // Schedule the initial one
|
||||||
|
cancelNextFrame();
|
||||||
|
// assert
|
||||||
|
expect(actualCancelledAnimationFrameId).to.equal(expectedCancelledAnimationFrameId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('automatically cancels the animation frame on cleanup', () => {
|
||||||
|
// arrange
|
||||||
|
let actualCancelledAnimationFrameId: AnimationFrameId | undefined;
|
||||||
|
let actualCleanupCallback: (() => void) | undefined;
|
||||||
|
const onTeardownCallback: RegisterTeardownCallbackFunction = (cleanupCallback) => {
|
||||||
|
actualCleanupCallback = cleanupCallback;
|
||||||
|
};
|
||||||
|
const expectedCancelledAnimationFrameId: AnimationFrameId = 5;
|
||||||
|
const requestAnimationFrame: RequestAnimationFrameFunction = () => {
|
||||||
|
return expectedCancelledAnimationFrameId;
|
||||||
|
};
|
||||||
|
const cancelAnimationFrame: CancelAnimationFrameFunction = (animationFrameId) => {
|
||||||
|
actualCancelledAnimationFrameId = animationFrameId;
|
||||||
|
};
|
||||||
|
const testContext = new TestContext()
|
||||||
|
.withOnTeardownCallback(onTeardownCallback)
|
||||||
|
.withRequestAnimationFrameFunction(requestAnimationFrame)
|
||||||
|
.withCancelAnimationFrame(cancelAnimationFrame);
|
||||||
|
// act
|
||||||
|
const { resetNextFrame } = testContext.useAnimationFrameLimiter();
|
||||||
|
resetNextFrame(() => {}); // Schedule the initial one
|
||||||
|
// assert
|
||||||
|
expectExists(actualCleanupCallback);
|
||||||
|
actualCleanupCallback();
|
||||||
|
expect(actualCancelledAnimationFrameId).to.equal(expectedCancelledAnimationFrameId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
class TestContext {
|
||||||
|
private cancelAnimationFrame: CancelAnimationFrameFunction = () => {};
|
||||||
|
|
||||||
|
private requestAnimationFrameFunction: RequestAnimationFrameFunction = () => Math.random();
|
||||||
|
|
||||||
|
private onTeardownCallback: RegisterTeardownCallbackFunction = () => {};
|
||||||
|
|
||||||
|
public withRequestAnimationFrameFunction(
|
||||||
|
requestAnimationFrameFunction: RequestAnimationFrameFunction,
|
||||||
|
): this {
|
||||||
|
this.requestAnimationFrameFunction = requestAnimationFrameFunction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withCancelAnimationFrame(
|
||||||
|
cancelAnimationFrame: CancelAnimationFrameFunction,
|
||||||
|
): this {
|
||||||
|
this.cancelAnimationFrame = cancelAnimationFrame;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withOnTeardownCallback(
|
||||||
|
registerCleanupCallback: RegisterTeardownCallbackFunction,
|
||||||
|
): this {
|
||||||
|
this.onTeardownCallback = registerCleanupCallback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public useAnimationFrameLimiter(): ReturnType<typeof useAnimationFrameLimiter> {
|
||||||
|
return useAnimationFrameLimiter(
|
||||||
|
this.cancelAnimationFrame,
|
||||||
|
this.requestAnimationFrameFunction,
|
||||||
|
this.onTeardownCallback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import { shallowRef } from 'vue';
|
||||||
|
import { useResizeObserver, type LifecycleHookRegistration, type ObservedElementReference } from '@/presentation/components/Shared/Hooks/Resize/UseResizeObserver';
|
||||||
|
import { flushPromiseResolutionQueue } from '@tests/unit/shared/PromiseInspection';
|
||||||
|
import type { AnimationFrameLimiter } from '@/presentation/components/Shared/Hooks/Resize/UseAnimationFrameLimiter';
|
||||||
|
import { ThrottleStub } from '@tests/unit/shared/Stubs/ThrottleStub';
|
||||||
|
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
|
||||||
|
|
||||||
|
describe('UseResizeObserver', () => {
|
||||||
|
it('registers observer once mounted', async () => {
|
||||||
|
// arrange
|
||||||
|
let registeredElement: Element | null = null;
|
||||||
|
const expectedElement = document.createElement('div');
|
||||||
|
const resizeObserverStub = createResizeObserverStub();
|
||||||
|
resizeObserverStub.observe = (element) => {
|
||||||
|
registeredElement = element;
|
||||||
|
};
|
||||||
|
// act
|
||||||
|
new TestContext()
|
||||||
|
.withObservedElementRef(shallowRef(expectedElement))
|
||||||
|
.withResizeObserver(resizeObserverStub)
|
||||||
|
.useResizeObserver();
|
||||||
|
await flushPromiseResolutionQueue();
|
||||||
|
// assert
|
||||||
|
expect(registeredElement).to.equal(expectedElement);
|
||||||
|
});
|
||||||
|
it('disposes observer once unmounted', async () => {
|
||||||
|
// arrange
|
||||||
|
let isObserverDisconnected = false;
|
||||||
|
const resizeObserverStub = createResizeObserverStub();
|
||||||
|
resizeObserverStub.disconnect = () => {
|
||||||
|
isObserverDisconnected = true;
|
||||||
|
};
|
||||||
|
let teardownCallback: (() => void) | undefined;
|
||||||
|
// act
|
||||||
|
new TestContext()
|
||||||
|
.withResizeObserver(resizeObserverStub)
|
||||||
|
.withOnTeardown((callback) => {
|
||||||
|
teardownCallback = callback;
|
||||||
|
})
|
||||||
|
.useResizeObserver();
|
||||||
|
await flushPromiseResolutionQueue();
|
||||||
|
expectExists(teardownCallback);
|
||||||
|
teardownCallback();
|
||||||
|
// assert
|
||||||
|
expect(isObserverDisconnected).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function createResizeObserverStub(): ResizeObserver {
|
||||||
|
return {
|
||||||
|
disconnect: () => {},
|
||||||
|
observe: () => {},
|
||||||
|
unobserve: () => {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFrameLimiterStub(): AnimationFrameLimiter {
|
||||||
|
return {
|
||||||
|
cancelNextFrame: () => {},
|
||||||
|
resetNextFrame: (callback) => { callback(); },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestContext {
|
||||||
|
private resizeObserver: ResizeObserver = createResizeObserverStub();
|
||||||
|
|
||||||
|
private observedElementRef: ObservedElementReference = shallowRef(document.createElement('div'));
|
||||||
|
|
||||||
|
private onSetup: LifecycleHookRegistration = (callback) => { callback(); };
|
||||||
|
|
||||||
|
private onTeardown: LifecycleHookRegistration = () => { };
|
||||||
|
|
||||||
|
public withResizeObserver(resizeObserver: ResizeObserver): this {
|
||||||
|
this.resizeObserver = resizeObserver;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withObservedElementRef(observedElementRef: ObservedElementReference): this {
|
||||||
|
this.observedElementRef = observedElementRef;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withOnSetup(onSetup: LifecycleHookRegistration): this {
|
||||||
|
this.onSetup = onSetup;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public withOnTeardown(onTeardown: LifecycleHookRegistration): this {
|
||||||
|
this.onTeardown = onTeardown;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public useResizeObserver() {
|
||||||
|
return useResizeObserver(
|
||||||
|
...this.buildParameters(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildParameters(): Parameters<typeof useResizeObserver> {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
observedElementRef: this.observedElementRef,
|
||||||
|
throttleInMs: 50,
|
||||||
|
observeCallback: () => {},
|
||||||
|
},
|
||||||
|
() => ({
|
||||||
|
resizeObserverReady: Promise.resolve(() => this.resizeObserver),
|
||||||
|
}),
|
||||||
|
() => createFrameLimiterStub(),
|
||||||
|
new ThrottleStub()
|
||||||
|
.withImmediateExecution(true)
|
||||||
|
.func,
|
||||||
|
this.onSetup,
|
||||||
|
this.onTeardown,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import type { CallbackType, throttle } from '@/application/Common/Timing/Throttle';
|
import type { CallbackType, ThrottleFunction } from '@/application/Common/Timing/Throttle';
|
||||||
|
|
||||||
export class ThrottleStub {
|
export class ThrottleStub {
|
||||||
public readonly throttleInitializationCallArgs: Array<Parameters<typeof throttle>> = [];
|
public readonly throttleInitializationCallArgs: Array<Parameters<ThrottleFunction>> = [];
|
||||||
|
|
||||||
public readonly throttledFunctionCallArgs = new Array<readonly unknown[]>();
|
public readonly throttledFunctionCallArgs = new Array<readonly unknown[]>();
|
||||||
|
|
||||||
private executeImmediately: boolean = false;
|
private executeImmediately: boolean = false;
|
||||||
|
|
||||||
public func = (callback: CallbackType, waitInMs: number): ReturnType<typeof throttle> => {
|
public func = (callback: CallbackType, waitInMs: number): ReturnType<ThrottleFunction> => {
|
||||||
this.throttleInitializationCallArgs.push([callback, waitInMs]);
|
this.throttleInitializationCallArgs.push([callback, waitInMs]);
|
||||||
return (...args: readonly unknown[]) => {
|
return (...args: readonly unknown[]) => {
|
||||||
this.throttledFunctionCallArgs.push([...args]);
|
this.throttledFunctionCallArgs.push([...args]);
|
||||||
|
|||||||
Reference in New Issue
Block a user