Refactor to Vue 3 recommended ESLint rules

These updates ensure better adherence to Vue 3 standards and improve
overall code quality and readability.

- Update ESLint configuration from Vue 2.x to Vue 3 rules.
- Switch from "essential" to strictest "recommended" ESLint ruleset.
- Adjust ESLint script to treat warnings as errors by using
  `--max-warnings=0` flag. This enforces stricter code quality controls
  provided by Vue 3 rules.
This commit is contained in:
undergroundwires
2023-11-17 13:57:13 +01:00
parent bf3426f91b
commit 4531645b4c
50 changed files with 231 additions and 166 deletions

View File

@@ -10,7 +10,7 @@ module.exports = {
},
extends: [
// Vue specific rules, eslint-plugin-vue
'plugin:vue/essential',
'plugin:vue/vue3-recommended',
// Extends eslint-config-airbnb
'@vue/eslint-config-airbnb-with-typescript',

2
package-lock.json generated
View File

@@ -6,7 +6,7 @@
"packages": {
"": {
"name": "privacy.sexy",
"version": "0.12.5",
"version": "0.12.7",
"hasInstallScript": true,
"dependencies": {
"@floating-ui/vue": "^1.0.2",

View File

@@ -24,7 +24,7 @@
"electron:preview": "electron-vite preview",
"electron:prebuild": "electron-vite build",
"electron:build": "electron-builder",
"lint:eslint": "eslint . --ignore-path .gitignore",
"lint:eslint": "eslint . --max-warnings=0 --ignore-path .gitignore",
"lint:md": "markdownlint **/*.md --ignore node_modules",
"lint:md:consistency": "remark . --frail --use remark-preset-lint-consistent",
"lint:md:relative-urls": "remark . --frail --use remark-validate-links",

View File

@@ -7,7 +7,10 @@
<TheCodeButtons class="app__row app__code-buttons" />
<TheFooter />
</div>
<component v-if="devToolkitComponent" :is="devToolkitComponent" />
<component
:is="devToolkitComponent"
v-if="devToolkitComponent"
/>
</div>
</template>

View File

@@ -1,8 +1,8 @@
<template>
<IconButton
text="Copy"
@click="copyCode"
icon-name="copy"
@click="copyCode"
/>
</template>

View File

@@ -2,8 +2,8 @@
<IconButton
v-if="canRun"
text="Run"
@click="executeCode"
icon-name="play"
@click="executeCode"
/>
</template>

View File

@@ -9,7 +9,9 @@
class="button__icon"
:icon="iconName"
/>
<div class="button__text">{{text}}</div>
<div class="button__text">
{{ text }}
</div>
</button>
</div>
</template>

View File

@@ -2,8 +2,8 @@
<div>
<IconButton
:text="isDesktopVersion ? 'Save' : 'Download'"
@click="saveCode"
:icon-name="isDesktopVersion ? 'floppy-disk' : 'file-arrow-down'"
@click="saveCode"
/>
<ModalDialog v-if="instructions" v-model="areInstructionsVisible">
<InstructionList :data="instructions" />

View File

@@ -9,7 +9,7 @@
class="copy-button"
@click="copyCode"
/>
<template v-slot:tooltip>
<template #tooltip>
Copy
</template>
</TooltipWrapper>

View File

@@ -1,7 +1,7 @@
<template>
<TooltipWrapper>
<AppIcon icon="circle-info" />
<template v-slot:tooltip>
<template #tooltip>
<slot />
</template>
</TooltipWrapper>

View File

@@ -20,19 +20,21 @@
<p>
<ol>
<li
v-for='(step, index) in data.steps'
v-bind:key="index"
v-for="(step, index) in data.steps"
:key="index"
class="step"
>
<div class="step__action">
<span>{{ step.action.instruction }}</span>
<div class="details-container" v-if="step.action.details">
<div v-if="step.action.details" class="details-container">
<!-- eslint-disable vue/no-v-html -->
<InfoTooltip><div v-html="step.action.details" /></InfoTooltip>
</div>
</div>
<div v-if="step.code" class="step__code">
<CodeInstruction>{{ step.code.instruction }}</CodeInstruction>
<div class="details-container" v-if="step.code.details">
<div v-if="step.code.details" class="details-container">
<!-- eslint-disable vue/no-v-html -->
<InfoTooltip><div v-html="step.code.details" /></InfoTooltip>
</div>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<div class="container" v-if="hasCode">
<div v-if="hasCode" class="container">
<CodeRunButton class="code-button" />
<CodeSaveButton class="code-button" />
<CodeCopyButton class="code-button" />

View File

@@ -1,7 +1,8 @@
<template>
<SizeObserver
v-on:sizeChanged="sizeChanged()"
v-non-collapsing>
v-non-collapsing
@size-changed="sizeChanged()"
>
<div
:id="editorId"
class="code-area"
@@ -24,18 +25,18 @@ import { NonCollapsing } from '@/presentation/components/Scripts/View/Cards/NonC
import ace from './ace-importer';
export default defineComponent({
props: {
theme: {
type: String,
default: undefined,
},
},
components: {
SizeObserver,
},
directives: {
NonCollapsing,
},
props: {
theme: {
type: String,
default: undefined,
},
},
setup(props) {
const { onStateChange, currentState } = injectKey((keys) => keys.useCollectionState);
const { events } = injectKey((keys) => keys.useAutoUnsubscribedEvents);

View File

@@ -6,9 +6,10 @@
<hr />
<button
v-for="action in devActions"
@click="action.handler"
:key="action.name"
type="button">
type="button"
@click="action.handler"
>
{{ action.name }}
</button>
</div>

View File

@@ -1,6 +1,8 @@
<template>
<div class="list">
<div v-if="label">{{ label }}:</div>
<div v-if="label">
{{ label }}:
</div>
<div class="items">
<slot />
</div>

View File

@@ -5,12 +5,13 @@
such as adding content in `::before` block without making it clickable.
-->
<span
v-bind:class="{
v-non-collapsing
:class="{
disabled: !enabled,
enabled: enabled,
}"
v-non-collapsing
@click="onClicked()">{{label}}</span>
@click="onClicked()"
>{{ label }}</span>
</span>
</template>

View File

@@ -7,7 +7,7 @@
:enabled="currentSelection !== SelectionType.None"
@click="selectType(SelectionType.None)"
/>
<template v-slot:tooltip>
<template #tooltip>
Deselect all selected scripts.
<br />
💡 Good start to dive deeper into tweaks and select only what you want.
@@ -21,7 +21,7 @@
:enabled="currentSelection !== SelectionType.Standard"
@click="selectType(SelectionType.Standard)"
/>
<template v-slot:tooltip>
<template #tooltip>
🛡 Balanced for privacy and functionality.
<br />
OS and applications will function normally.
@@ -37,7 +37,7 @@
:enabled="currentSelection !== SelectionType.Strict"
@click="selectType(SelectionType.Strict)"
/>
<template v-slot:tooltip>
<template #tooltip>
🚫 Stronger privacy, disables risky functions that may leak your data.
<br />
Double check to remove scripts where you would trade functionality for privacy
@@ -53,7 +53,7 @@
:enabled="currentSelection !== SelectionType.All"
@click="selectType(SelectionType.All)"
/>
<template v-slot:tooltip>
<template #tooltip>
🔒 Strongest privacy, disabling any functionality that may leak your data.
<br />
🛑 Not designed for daily users, it will break important functionalities.

View File

@@ -4,8 +4,8 @@
v-for="os in allOses"
:key="os.name"
:enabled="currentOs !== os.os"
@click="changeOs(os.os)"
:label="os.name"
@click="changeOs(os.os)"
/>
</MenuOptionList>
</template>

View File

@@ -3,9 +3,10 @@
<TheSelector class="item" />
<TheOsChanger class="item" />
<TheViewChanger
v-if="!isSearching"
class="item"
v-on:viewChanged="$emit('viewChanged', $event)"
v-if="!isSearching" />
@view-changed="$emit('viewChanged', $event)"
/>
</div>
</template>
@@ -17,6 +18,7 @@ import { IEventSubscription } from '@/infrastructure/Events/IEventSource';
import TheOsChanger from './TheOsChanger.vue';
import TheSelector from './Selector/TheSelector.vue';
import TheViewChanger from './View/TheViewChanger.vue';
import { ViewType } from './View/ViewType';
export default defineComponent({
components: {
@@ -24,6 +26,11 @@ export default defineComponent({
TheOsChanger,
TheViewChanger,
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
viewChanged: (viewType: ViewType) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
setup() {
const { onStateChange } = injectKey((keys) => keys.useCollectionState);
const { events } = injectKey((keys) => keys.useAutoUnsubscribedEvents);

View File

@@ -1,7 +1,8 @@
<template>
<MenuOptionList
label="View"
class="part">
class="part"
>
<MenuOptionListItem
v-for="view in viewOptions"
:key="view.type"

View File

@@ -1,14 +1,14 @@
<template>
<div
class="slider"
v-bind:style="{
:style="{
'--vertical-margin': verticalMargin,
'--first-min-width': firstMinWidth,
'--first-initial-width': firstInitialWidth,
'--second-min-width': secondMinWidth,
}"
>
<div class="first" ref="firstElement">
<div ref="firstElement" class="first">
<slot name="first" />
</div>
<SliderHandle class="handle" @resized="onResize($event)" />

View File

@@ -2,7 +2,8 @@
<div
class="handle"
:style="{ cursor: cursorCssValue }"
@mousedown="startResize">
@mousedown="startResize"
>
<div class="line" />
<AppIcon
class="icon"

View File

@@ -1,17 +1,17 @@
<template>
<div class="scripts">
<TheScriptsMenu v-on:viewChanged="currentView = $event" />
<TheScriptsMenu @view-changed="currentView = $event" />
<HorizontalResizeSlider
class="row"
verticalMargin="15px"
firstInitialWidth="55%"
firstMinWidth="20%"
secondMinWidth="20%"
vertical-margin="15px"
first-initial-width="55%"
first-min-width="20%"
second-min-width="20%"
>
<template v-slot:first>
<TheScriptsView :currentView="currentView" />
<template #first>
<TheScriptsView :current-view="currentView" />
</template>
<template v-slot:second>
<template #second>
<TheCodeArea theme="xcode" />
</template>
</HorizontalResizeSlider>

View File

@@ -1,5 +1,7 @@
<template>
<SizeObserver v-on:widthChanged="width = $event">
<SizeObserver
@width-changed="width = $event"
>
<transition name="fade-transition">
<div v-if="width">
<!-- <div id="responsivity-debug">
@@ -14,21 +16,23 @@
class="cards"
>
<CardListItem
v-for="categoryId of categoryIds"
:key="categoryId"
class="card"
v-bind:class="{
:class="{
'small-screen': width <= 500,
'medium-screen': width > 500 && width < 750,
'big-screen': width >= 750,
}"
v-for="categoryId of categoryIds"
:data-category="categoryId"
v-bind:key="categoryId"
:categoryId="categoryId"
:activeCategoryId="activeCategoryId"
v-on:cardExpansionChanged="onSelected(categoryId, $event)"
:category-id="categoryId"
:active-category-id="activeCategoryId"
@card-expansion-changed="onSelected(categoryId, $event)"
/>
</div>
<div v-else class="error">Something went bad 😢</div>
<div v-else class="error">
Something went bad 😢
</div>
</div>
</transition>
</SizeObserver>

View File

@@ -1,18 +1,20 @@
<template>
<div
ref="cardElement"
class="card"
v-on:click="isExpanded = !isExpanded"
v-bind:class="{
:class="{
'is-collapsed': !isExpanded,
'is-inactive': activeCategoryId && activeCategoryId != categoryId,
'is-expanded': isExpanded,
}"
ref="cardElement">
@click="isExpanded = !isExpanded"
>
<div class="card__inner">
<!-- Title -->
<span
v-if="cardTitle.length > 0"
class="card__inner__title"
v-if="cardTitle && cardTitle.length > 0">
>
<span>{{ cardTitle }}</span>
</span>
<span v-else>Oh no 😢</span>
@@ -24,17 +26,17 @@
<!-- Indeterminate and full states -->
<CardSelectionIndicator
class="card__inner__selection_indicator"
:categoryId="categoryId"
:category-id="categoryId"
/>
</div>
<div class="card__expander" v-on:click.stop>
<div class="card__expander" @click.stop>
<div class="card__expander__content">
<ScriptsTree :categoryId="categoryId" />
<ScriptsTree :category-id="categoryId" />
</div>
<div class="card__expander__close-button">
<AppIcon
icon="xmark"
v-on:click="collapse()"
@click="collapse()"
/>
</div>
</div>

View File

@@ -1,12 +1,12 @@
<template>
<div>
<AppIcon
icon="battery-half"
v-if="isAnyChildSelected && !areAllChildrenSelected"
icon="battery-half"
/>
<AppIcon
icon="battery-full"
v-if="areAllChildrenSelected"
icon="battery-full"
/>
</div>
</template>

View File

@@ -10,13 +10,14 @@
</div>
</template>
</div>
<div v-else> <!-- Searching -->
<div v-else>
<!-- Searching -->
<div class="search">
<div class="search__query">
<div>Searching for "{{ trimmedSearchQuery }}"</div>
<div
class="search__query__close-button"
v-on:click="clearSearchQuery()"
@click="clearSearchQuery()"
>
<AppIcon icon="xmark" />
</div>

View File

@@ -6,22 +6,26 @@
</div>
<ToggleDocumentationButton
v-if="docs && docs.length > 0"
v-on:show="isExpanded = true"
v-on:hide="isExpanded = false"
@show="isExpanded = true"
@hide="isExpanded = false"
/>
</div>
<div
v-if="docs && docs.length > 0 && isExpanded"
class="docs"
v-bind:class="{ 'docs-expanded': isExpanded, 'docs-collapsed': !isExpanded }"
:class="{
'docs-expanded': isExpanded,
'docs-collapsed': !isExpanded,
}"
>
<DocumentationText
:docs="docs"
class="text"
v-bind:class="{
:class="{
expanded: isExpanded,
collapsed: !isExpanded,
}" />
}"
/>
</div>
</div>
</template>

View File

@@ -1,8 +1,9 @@
<template>
<!-- eslint-disable vue/no-v-html -->
<div
class="documentation-text"
@click.stop
v-html="renderedText"
v-on:click.stop
/>
</template>

View File

@@ -2,9 +2,9 @@
<a
class="button"
target="_blank"
v-bind:class="{ 'button-on': isOn }"
v-on:click.stop
v-on:click="toggle()"
:class="{ 'button-on': isOn }"
@click.stop
@click="toggle()"
>
<AppIcon icon="circle-info" />
</a>

View File

@@ -1,11 +1,14 @@
<template>
<DocumentableNode :docs="nodeMetadata.docs">
<div id="node">
<div class="item text">{{ nodeMetadata.text }}</div>
<div class="item text">
{{ nodeMetadata.text }}
</div>
<RevertToggle
class="item"
v-if="nodeMetadata.isReversible"
:node="nodeMetadata" />
class="item"
:node="nodeMetadata"
/>
</div>
</DocumentableNode>
</template>

View File

@@ -1,7 +1,7 @@
<template>
<ToggleSwitch
v-model="isReverted"
:stopClickPropagation="true"
:stop-click-propagation="true"
:label="'revert'"
/>
</template>

View File

@@ -4,9 +4,9 @@
@click="handleClickPropagation"
>
<input
v-model="isChecked"
type="checkbox"
class="toggle-input"
v-model="isChecked"
>
<div class="toggle-animation">
<span class="label-off">{{ label }}</span>

View File

@@ -2,13 +2,13 @@
<span id="container">
<span v-if="initialNodes.length">
<TreeView
:initialNodes="initialNodes"
:selectedLeafNodeIds="selectedScriptNodeIds"
:latestFilterEvent="latestFilterEvent"
@nodeStateChanged="handleNodeChangedEvent($event)"
:initial-nodes="initialNodes"
:selected-leaf-node-ids="selectedScriptNodeIds"
:latest-filter-event="latestFilterEvent"
@node-state-changed="handleNodeChangedEvent($event)"
>
<template v-slot:node-content="{ nodeMetadata }">
<NodeContent :nodeMetadata="nodeMetadata" />
<template #node-content="{ nodeMetadata }">
<NodeContent :node-metadata="nodeMetadata" />
</template>
</TreeView>
</span>
@@ -28,16 +28,16 @@ import { TreeNodeStateChangedEmittedEvent } from './TreeView/Bindings/TreeNodeSt
import { useSelectedScriptNodeIds } from './TreeViewAdapter/UseSelectedScriptNodeIds';
export default defineComponent({
components: {
TreeView,
NodeContent,
},
props: {
categoryId: {
type: [Number],
default: undefined,
},
},
components: {
TreeView,
NodeContent,
},
setup(props) {
const useUserCollectionStateHook = injectKey((keys) => keys.useUserSelectionState);
const { selectedScriptNodeIds } = useSelectedScriptNodeIds(useUserCollectionStateHook);

View File

@@ -2,10 +2,11 @@
<div class="wrapper">
<div
class="expansible-node"
@click="toggleCheck"
:style="{
'padding-left': `${currentNode.hierarchy.depthInTree * 24}px`,
}">
}"
@click="toggleCheck"
>
<div
class="expand-collapse-arrow"
:class="{
@@ -15,10 +16,10 @@
@click.stop="toggleExpand"
/>
<LeafTreeNode
:nodeId="nodeId"
:treeRoot="treeRoot"
:node-id="nodeId"
:tree-root="treeRoot"
>
<template v-slot:node-content="slotProps">
<template #node-content="slotProps">
<slot name="node-content" v-bind="slotProps" />
</template>
</LeafTreeNode>
@@ -32,11 +33,11 @@
<HierarchicalTreeNode
v-for="id in renderedNodeIds"
:key="id"
:nodeId="id"
:treeRoot="treeRoot"
:renderingStrategy="renderingStrategy"
:node-id="id"
:tree-root="treeRoot"
:rendering-strategy="renderingStrategy"
>
<template v-slot:node-content="slotProps">
<template #node-content="slotProps">
<slot name="node-content" v-bind="slotProps" />
</template>
</HierarchicalTreeNode>

View File

@@ -5,11 +5,11 @@
>
<div
class="node focusable"
@focus="onNodeFocus"
tabindex="-1"
:class="{
'keyboard-focus': hasKeyboardFocus,
}"
tabindex="-1"
@focus="onNodeFocus"
>
<div
class="checkbox"
@@ -22,7 +22,7 @@
<div class="content">
<slot
name="node-content"
:nodeMetadata="currentNode.metadata"
:node-metadata="currentNode.metadata"
/>
</div>
</div>

View File

@@ -5,11 +5,11 @@
<HierarchicalTreeNode
v-for="nodeId in renderedNodeIds"
:key="nodeId"
:nodeId="nodeId"
:treeRoot="treeRoot"
:renderingStrategy="renderingStrategy"
:node-id="nodeId"
:tree-root="treeRoot"
:rendering-strategy="renderingStrategy"
>
<template v-slot:node-content="slotProps">
<template #node-content="slotProps">
<slot v-bind="slotProps" />
</template>
</HierarchicalTreeNode>

View File

@@ -1,10 +1,10 @@
<template>
<div
class="tree"
ref="treeContainerElement"
class="tree"
>
<TreeRoot :treeRoot="tree" :renderingStrategy="nodeRenderingScheduler">
<template v-slot="slotProps">
<TreeRoot :tree-root="tree" :rendering-strategy="nodeRenderingScheduler">
<template #default="slotProps">
<slot name="node-content" v-bind="slotProps" />
</template>
</TreeRoot>
@@ -34,11 +34,6 @@ export default defineComponent({
components: {
TreeRoot,
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
nodeStateChanged: (node: TreeNodeStateChangedEmittedEvent) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
props: {
initialNodes: {
type: Array as PropType<readonly TreeInputNodeData[]>,
@@ -53,6 +48,11 @@ export default defineComponent({
default: () => [],
},
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
nodeStateChanged: (node: TreeNodeStateChangedEmittedEvent) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
setup(props, { emit }) {
const treeContainerElement = shallowRef<HTMLElement | undefined>();

View File

@@ -1,9 +1,11 @@
<template>
<div
class="inline-icon"
v-html="svgContent"
class="icon-container"
@click="onClicked"
/>
>
<!-- eslint-disable vue/no-v-html -->
<div class="inline-icon" v-html="svgContent" />
</div>
</template>
<script lang="ts">
@@ -41,13 +43,14 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.icon-container {
display: inline-block;
.inline-icon {
display: inline-block;
:deep(svg) { // using :deep because when v-html is used the content doesn't go through Vue's template compiler.
display: inline-block;
height: 1em;
overflow: visible;
vertical-align: -0.125em;
}
}
}
</style>

View File

@@ -4,14 +4,14 @@
class="modal-container"
>
<ModalOverlay
@transitionedOut="onOverlayTransitionedOut"
@click="onBackgroundOverlayClick"
:show="isOpen"
@transitioned-out="onOverlayTransitionedOut"
@click="onBackgroundOverlayClick"
/>
<ModalContent
class="modal-content"
:show="isOpen"
@transitionedOut="onContentTransitionedOut"
@transitioned-out="onContentTransitionedOut"
>
<slot />
</ModalContent>
@@ -34,11 +34,6 @@ export default defineComponent({
ModalOverlay,
ModalContent,
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
'update:modelValue': (isOpen: boolean) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
props: {
modelValue: {
type: Boolean,
@@ -49,6 +44,11 @@ export default defineComponent({
default: true,
},
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
'update:modelValue': (isOpen: boolean) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
setup(props, { emit }) {
const isRendered = ref(false);
const isOpen = ref(false);

View File

@@ -26,17 +26,17 @@ export default defineComponent({
ModalContainer,
AppIcon,
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
'update:modelValue': (isOpen: boolean) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
props: {
modelValue: {
type: Boolean,
required: true,
},
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
'update:modelValue': (isOpen: boolean) => true,
/* eslint-enable @typescript-eslint/no-unused-vars */
},
setup(props, { emit }) {
const showDialog = computed({
get: () => props.modelValue,

View File

@@ -5,8 +5,9 @@
It allows the tooltip content to calculate its position based on the trigger's location.
-->
<div
ref="triggeringElement"
class="tooltip__trigger"
ref="triggeringElement">
>
<slot />
</div>
<div class="tooltip__overlay">

View File

@@ -1,17 +1,22 @@
<template>
<span
class="container"
v-bind:class="{
:class="{
'container-unsupported': !hasCurrentOsDesktopVersion,
'container-supported': hasCurrentOsDesktopVersion,
}">
}"
>
<span class="description">
<AppIcon class="description__icon" icon="desktop" />
<span class="description__text">For desktop:</span>
</span>
<span class="urls">
<span class="urls__url" v-for="os of supportedDesktops" v-bind:key="os">
<DownloadUrlListItem :operatingSystem="os" />
<span
v-for="os of supportedDesktops"
:key="os"
class="urls__url"
>
<DownloadUrlListItem :operating-system="os" />
</span>
</span>
</span>

View File

@@ -2,10 +2,11 @@
<span class="url">
<a
:href="downloadUrl"
v-bind:class="{
:class="{
url__active: hasCurrentOsDesktopVersion && isCurrentOs,
url__inactive: hasCurrentOsDesktopVersion && !isCurrentOs,
}">{{ operatingSystemName }}</a>
}"
>{{ operatingSystemName }}</a>
</span>
</template>

View File

@@ -1,29 +1,39 @@
<template>
<div class="privacy-policy">
<div v-if="!isDesktop" class="line">
<div class="line__emoji">🚫🍪</div>
<div class="line__emoji">
🚫🍪
</div>
<div>No cookies!</div>
</div>
<div v-if="isDesktop" class="line">
<div class="line__emoji">🚫🌐</div>
<div class="line__emoji">
🚫🌐
</div>
<div>
Everything is offline, except single request GitHub
to check for updates on application start.
</div>
</div>
<div class="line">
<div class="line__emoji">🚫👀</div>
<div class="line__emoji">
🚫👀
</div>
<div>No user behavior / IP address collection!</div>
</div>
<div class="line">
<div class="line__emoji">🤖</div>
<div class="line__emoji">
🤖
</div>
<div>
All transparent: Deployed automatically from the master branch
of the <a :href="repositoryUrl" target="_blank" rel="noopener noreferrer">source code</a> with no changes.
</div>
</div>
<div v-if="!isDesktop" class="line">
<div class="line__emoji">📈</div>
<div class="line__emoji">
📈
</div>
<div>
Basic <a href="https://aws.amazon.com/cloudfront/reporting/" target="_blank" rel="noopener noreferrer">CDN statistics</a>
are collected by AWS but they cannot be traced to you or your behavior.
@@ -31,11 +41,14 @@
</div>
</div>
<div class="line">
<div class="line__emoji">🎉</div>
<div class="line__emoji">
🎉
</div>
<div>
As almost no data is collected, the application gets better
only with your active feedback.
Feel free to <a :href="feedbackUrl" target="_blank" rel="noopener noreferrer">create an issue</a> 😊</div>
Feel free to <a :href="feedbackUrl" target="_blank" rel="noopener noreferrer">create an issue</a> 😊
</div>
</div>
</div>
</template>

View File

@@ -1,7 +1,11 @@
<template>
<div id="container">
<h1 class="child title">{{ title }}</h1>
<h2 class="child subtitle">{{ subtitle }}</h2>
<h1 class="child title">
{{ title }}
</h1>
<h2 class="child subtitle">
{{ subtitle }}
</h2>
</div>
</template>

View File

@@ -1,10 +1,10 @@
<template>
<div class="search" v-non-collapsing>
<div v-non-collapsing class="search">
<input
v-model="searchQuery"
type="search"
class="search-term"
:placeholder="searchPlaceholder"
v-model="searchQuery"
>
<div class="icon-wrapper">
<AppIcon icon="magnifying-glass" />

View File

@@ -201,14 +201,6 @@ function mountToggleSwitchParent(options?: {
ToggleSwitch,
},
emits: [parentClickEventName],
template: `
<div @click="handleParentClick">
<ToggleSwitch
:stopClickPropagation="stopClickPropagation"
:label="'test-label'"
/>
</div>
`,
setup(_, { emit }) {
const stopClickPropagation = options?.stopClickPropagation;
@@ -221,6 +213,14 @@ function mountToggleSwitchParent(options?: {
stopClickPropagation,
};
},
template: `
<div @click="handleParentClick">
<ToggleSwitch
:stopClickPropagation="stopClickPropagation"
:label="'test-label'"
/>
</div>
`,
});
const wrapper = mount(
parentComponent,

View File

@@ -61,6 +61,7 @@ describe('AppIcon.vue', () => {
// act
await wrapper.trigger('click');
await nextTick();
// assert
expect(wrapper.emitted().click).to.have.lengthOf(1);

View File

@@ -8,7 +8,6 @@ export function createSizeObserverStub(
) {
const component = defineComponent({
name: COMPONENT_SIZE_OBSERVER_NAME,
template: `<div id="${COMPONENT_SIZE_OBSERVER_NAME}-stub"><slot /></div>`,
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
widthChanged: (newWidth: number) => true,
@@ -19,6 +18,7 @@ export function createSizeObserverStub(
emit('widthChanged', newValue);
});
},
template: `<div id="${COMPONENT_SIZE_OBSERVER_NAME}-stub"><slot /></div>`,
});
return {
name: COMPONENT_SIZE_OBSERVER_NAME,