Merge branch 'service-worker' into 'master'

Service worker & homepage

See merge request framasoft/mobilizon!943
This commit is contained in:
Thomas Citharel 2021-06-20 12:09:44 +00:00
commit a51723e239
13 changed files with 238 additions and 119 deletions

View File

@ -70,7 +70,6 @@
"@types/prosemirror-model": "^1.7.2",
"@types/prosemirror-state": "^1.2.4",
"@types/prosemirror-view": "^1.11.4",
"@types/vuedraggable": "^2.23.0",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~5.0.0-beta.2",

View File

@ -117,11 +117,38 @@ export default class App extends Vue {
window.addEventListener("offline", () => {
this.online = false;
this.showOfflineNetworkWarning();
console.log("offline");
console.debug("offline");
});
window.addEventListener("online", () => {
this.online = true;
console.log("online");
console.debug("online");
});
document.addEventListener("refreshApp", (event: Event) => {
this.$buefy.snackbar.open({
queue: false,
indefinite: true,
type: "is-primary",
actionText: this.$t("Update app") as string,
cancelText: this.$t("Ignore") as string,
message: this.$t("A new version is available.") as string,
onAction: async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const detail = event.detail;
const registration = detail as ServiceWorkerRegistration;
try {
await this.refreshApp(registration);
window.location.reload();
} catch (err) {
console.error(err);
this.$notifier.error(
this.$t(
"An error has occured while refreshing the page."
) as string
);
}
},
});
});
this.interval = setInterval(async () => {
@ -138,6 +165,30 @@ export default class App extends Vue {
}, 60000);
}
private async refreshApp(
registration: ServiceWorkerRegistration
): Promise<any> {
const worker = registration.waiting;
if (!worker) {
return Promise.resolve();
}
console.debug("Doing worker.skipWaiting().");
return new Promise((resolve, reject) => {
const channel = new MessageChannel();
channel.port1.onmessage = (event) => {
console.debug("Done worker.skipWaiting().");
if (event.data.error) {
reject(event.data);
} else {
resolve(event.data);
}
};
console.debug("calling skip waiting");
worker?.postMessage({ type: "skip-waiting" }, [channel.port2]);
});
}
showOfflineNetworkWarning(): void {
this.$notifier.error(this.$t("You are offline") as string);
}

View File

@ -179,7 +179,7 @@
<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { Editor, EditorContent, BubbleMenu } from "@tiptap/vue-2";
import { defaultExtensions } from "@tiptap/starter-kit";
import StarterKit from "@tiptap/starter-kit";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
@ -241,6 +241,7 @@ export default class EditorComponent extends Vue {
mounted(): void {
this.editor = new Editor({
extensions: [
StarterKit,
Document,
Paragraph,
Text,
@ -253,7 +254,6 @@ export default class EditorComponent extends Vue {
CharacterCount.configure({
limit: this.maxSize,
}),
...defaultExtensions(),
],
injectCSS: false,
content: this.value,

View File

@ -2,7 +2,13 @@
<article class="box">
<div class="identity-header">
<figure class="image is-24x24" v-if="participation.actor.avatar">
<img class="is-rounded" :src="participation.actor.avatar.url" alt="" />
<img
class="is-rounded"
:src="participation.actor.avatar.url"
alt=""
height="24"
width="24"
/>
</figure>
{{ displayNameAndUsername(participation.actor) }}
</div>

View File

@ -30,6 +30,6 @@ export default class RecentEventCardWrapper extends Vue {
</script>
<style lang="scss" scoped>
p.time {
color: $orange-2;
color: $violet-3;
}
</style>

View File

@ -857,7 +857,6 @@
"Your city or region and the radius will only be used to suggest you events nearby. The event radius will consider the administrative center of the area.": "Your city or region and the radius will only be used to suggest you events nearby. The event radius will consider the administrative center of the area.",
"Your upcoming events": "Your upcoming events",
"Last published events": "Last published events",
"On {instance}": "On {instance}",
"Events nearby": "Events nearby",
"Within {number} kilometers of {place}": "|Within one kilometer of {place}|Within {number} kilometers of {place}",
"@{username}": "@{username}",
@ -1047,5 +1046,12 @@
"Share this group": "Share this group",
"This group is accessible only through it's link. Be careful where you post this link.": "This group is accessible only through it's link. Be careful where you post this link.",
"{count} members": "No members|One member|{count} members",
"Share": "Share"
"Share": "Share",
"Update app": "Update app",
"Ignore": "Ignore",
"A new version is available.": "A new version is available.",
"An error has occured while refreshing the page.": "An error has occured while refreshing the page.",
"Join group {group}": "Join group {group}",
"Public preview": "Public preview",
"On {instance} and other federated instances": "On {instance} and other federated instances"
}

View File

@ -561,7 +561,6 @@
"On {date} ending at {endTime}": "Le {date}, se terminant à {endTime}",
"On {date} from {startTime} to {endTime}": "Le {date} de {startTime} à {endTime}",
"On {date} starting at {startTime}": "Le {date} à partir de {startTime}",
"On {instance}": "Sur {instance}",
"Ongoing tasks": "Tâches en cours",
"Only accessible through link": "Accessible uniquement par le lien",
"Only accessible through link (private)": "Uniquement accessible par lien (privé)",
@ -1138,5 +1137,12 @@
"Share this group": "Partager ce groupe",
"This group is accessible only through it's link. Be careful where you post this link.": "Ce groupe est accessible uniquement à travers son lien. Faites attention où vous le diffusez.",
"{count} members": "Aucun membre|Un⋅e membre|{count} membres",
"Share": "Partager"
"Share": "Partager",
"Update app": "Mettre à jour",
"Ignore": "Ignorer",
"A new version is available.": "Une nouvelle version est disponible.",
"An error has occured while refreshing the page.": "Une erreur est survenue lors du rafraîchissement de la page.",
"Join group {group}": "Rejoindre le groupe {group}",
"Public preview": "Aperçu public",
"On {instance} and other federated instances": "Sur {instance} et d'autres instances fédérées"
}

View File

@ -5,25 +5,27 @@ import { register } from "register-service-worker";
if ("serviceWorker" in navigator && isProduction()) {
register(`${process.env.BASE_URL}service-worker.js`, {
ready() {
console.log(
console.debug(
"App is being served from cache by a service worker.\n" +
"For more details, visit https://goo.gl/AFskqB"
);
},
registered() {
console.log("Service worker has been registered.");
console.debug("Service worker has been registered.");
},
cached() {
console.log("Content has been cached for offline use.");
console.debug("Content has been cached for offline use.");
},
updatefound() {
console.log("New content is downloading.");
console.debug("New content is downloading.");
},
updated() {
console.log("New content is available; please refresh.");
updated(registration: ServiceWorkerRegistration) {
const event = new CustomEvent("refreshApp", { detail: registration });
document.dispatchEvent(event);
console.debug("New content is available; please refresh.");
},
offline() {
console.log(
console.debug(
"No internet connection found. App is running in offline mode."
);
},
@ -34,6 +36,5 @@ if ("serviceWorker" in navigator && isProduction()) {
}
function isProduction(): boolean {
return true;
// return process.env.NODE_ENV === "production";
return process.env.NODE_ENV === "production";
}

View File

@ -42,10 +42,11 @@ registerRoute(
// Cache CSS, JS, and Web Worker requests with a Stale While Revalidate strategy
registerRoute(
// Check to see if the request's destination is style for stylesheets, script for JavaScript, or worker for web worker
// Check to see if the request's destination is style for stylesheets, script for JavaScript, font, or worker for web worker
({ request }) =>
request.destination === "style" ||
request.destination === "script" ||
request.destination === "font" ||
request.destination === "worker",
// Use a Stale While Revalidate caching strategy
new StaleWhileRevalidate({
@ -82,6 +83,24 @@ registerRoute(
})
);
async function isClientFocused(): Promise<boolean> {
const windowClients = await self.clients.matchAll({
type: "window",
includeUncontrolled: true,
});
let clientIsFocused = false;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i] as WindowClient;
if (windowClient.focused) {
clientIsFocused = true;
break;
}
}
return clientIsFocused;
}
self.addEventListener("push", async (event: PushEvent) => {
if (!event.data) return;
const payload = event.data.json();
@ -98,7 +117,15 @@ self.addEventListener("push", async (event: PushEvent) => {
},
};
event.waitUntil(self.registration.showNotification(payload.title, options));
event.waitUntil(
(async () => {
if (await isClientFocused()) {
// No need to show a notification, client already focused
return;
}
self.registration.showNotification(payload.title, options);
})()
);
});
self.addEventListener("notificationclick", function (event: NotificationEvent) {
@ -111,6 +138,7 @@ self.addEventListener("notificationclick", function (event: NotificationEvent) {
(async () => {
const clientList = await self.clients.matchAll({
type: "window",
includeUncontrolled: true,
});
for (let i = 0; i < clientList.length; i++) {
const client = clientList[i] as WindowClient;
@ -124,3 +152,17 @@ self.addEventListener("notificationclick", function (event: NotificationEvent) {
})()
);
});
self.addEventListener("message", (event: ExtendableMessageEvent) => {
const replyPort = event.ports[0];
const message = event.data;
if (replyPort && message && message.type === "skip-waiting") {
console.log("doing skip waiting");
event.waitUntil(
self.skipWaiting().then(
() => replyPort.postMessage({ error: null }),
(error) => replyPort.postMessage({ error })
)
);
}
});

View File

@ -128,10 +128,6 @@ $subtitle-size: 32px;
$subtitle-sub-size: 30px;
$subtitle-sup-size: 15px;
.title {
margin: 30px auto 45px;
}
.subtitle {
background: $secondary;
display: inline;

View File

@ -52,11 +52,13 @@
v-if="config && (!currentUser.id || !currentActor.id)"
>
<section class="events-recent">
<h2 class="is-size-2 has-text-weight-bold">
<h2 class="title">
{{ $t("Last published events") }}
</h2>
<p>
{{ $t("On {instance}", { instance: config.name }) }}
<i18n tag="span" path="On {instance} and other federated instances">
<b slot="instance">{{ config.name }}</b>
</i18n>
<b-loading :active.sync="$apollo.loading" />
</p>
<b-loading :active.sync="$apollo.loading" />
@ -176,7 +178,7 @@
class="container section"
v-if="config && loggedUser && loggedUser.settings"
>
<section v-if="currentActor.id">
<section v-if="currentActor.id && (welcomeBack || newRegisteredUser)">
<b-message type="is-info" v-if="welcomeBack">{{
$t("Welcome back {username}!", {
username: currentActor.displayName(),
@ -189,34 +191,33 @@
}}</b-message>
</section>
<!-- Your upcoming events -->
<section v-if="canShowMyUpcomingEvents" class="container">
<h3 class="title">{{ $t("Your upcoming events") }}</h3>
<section v-if="canShowMyUpcomingEvents">
<h2 class="title">{{ $t("Your upcoming events") }}</h2>
<b-loading :active.sync="$apollo.loading" />
<div v-for="row of goingToEvents" class="upcoming-events" :key="row[0]">
<span
<p
class="date-component-container"
v-if="isInLessThanSevenDays(row[0])"
>
<date-component :date="row[0]" />
<subtitle v-if="isToday(row[0])">{{
<span v-if="isToday(row[0])">{{
$tc("You have one event today.", row[1].length, {
count: row[1].length,
})
}}</subtitle>
<subtitle v-else-if="isTomorrow(row[0])">{{
}}</span>
<span v-else-if="isTomorrow(row[0])">{{
$tc("You have one event tomorrow.", row[1].length, {
count: row[1].length,
})
}}</subtitle>
<subtitle v-else-if="isInLessThanSevenDays(row[0])">
}}</span>
<span v-else-if="isInLessThanSevenDays(row[0])">
{{
$tc("You have one event in {days} days.", row[1].length, {
count: row[1].length,
days: calculateDiffDays(row[0]),
})
}}
</subtitle>
</span>
</span>
</p>
<div>
<EventListCard
v-for="participation in thisWeek(row)"
@ -232,9 +233,13 @@
>
</span>
</section>
<hr
class="home-separator"
v-if="canShowMyUpcomingEvents && canShowLastWeekEvents"
/>
<!-- Last week events -->
<section v-if="canShowLastWeekEvents">
<h3 class="title">{{ $t("Last week") }}</h3>
<h2 class="title">{{ $t("Last week") }}</h2>
<b-loading :active.sync="$apollo.loading" />
<div>
<EventListCard
@ -246,9 +251,13 @@
/>
</div>
</section>
<hr
class="home-separator"
v-if="canShowLastWeekEvents && canShowCloseEvents"
/>
<!-- Events close to you -->
<section class="events-close" v-if="canShowCloseEvents">
<h2 class="is-size-2 has-text-weight-bold">
<h2 class="title">
{{ $t("Events nearby") }}
</h2>
<p>
@ -289,11 +298,13 @@
"
/>
<section class="events-recent">
<h2 class="is-size-2 has-text-weight-bold">
<h2 class="title">
{{ $t("Last published events") }}
</h2>
<p>
{{ $t("On {instance}", { instance: config.name }) }}
<i18n tag="span" path="On {instance} and other federated instances">
<b slot="instance">{{ config.name }}</b>
</i18n>
<b-loading :active.sync="$apollo.loading" />
</p>
@ -629,20 +640,16 @@ main > div > .container {
.date-component-container {
display: flex;
align-items: center;
margin: 1.5rem auto;
margin: 0.5rem auto 1rem;
h3.subtitle {
margin-left: 7px;
}
}
section.container {
margin: auto auto 3rem;
}
span.view-all {
display: block;
margin-top: 2rem;
margin-top: 1rem;
text-align: right;
a {
@ -688,8 +695,8 @@ section.hero {
}
#recent_events {
padding: 1rem 0;
min-height: calc(100vh - 400px);
padding: 0;
min-height: 20vh;
z-index: 10;
.title {
@ -697,7 +704,7 @@ section.hero {
}
.columns {
margin: 0rem auto 3rem;
margin: 0 auto;
}
}
@ -761,4 +768,11 @@ section.hero {
.clickable {
cursor: pointer;
}
.title {
font-size: 27px;
&:not(:last-child) {
margin-bottom: 0.5rem;
}
}
</style>

View File

@ -26,6 +26,7 @@ import {
typePolicies,
refreshAccessToken,
} from "./apollo/utils";
import { GraphQLError } from "graphql";
// Install the vue plugin
Vue.use(VueApollo);
@ -120,10 +121,14 @@ const errorLink = onError(
}
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
graphQLErrors.map(
(graphQLError: GraphQLError & { status_code?: number }) => {
if (graphQLError?.status_code !== 401) {
console.log(
`[GraphQL error]: Message: ${graphQLError.message}, Location: ${graphQLError.locations}, Path: ${graphQLError.path}`
);
}
}
);
}

View File

@ -1483,10 +1483,10 @@
ejs "^2.6.1"
magic-string "^0.25.0"
"@tiptap/core@^2.0.0-beta.41", "@tiptap/core@^2.0.0-beta.83":
version "2.0.0-beta.83"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.83.tgz#29bfd96591651469ec4d22dfb1bbaba8d74877ce"
integrity sha512-F6nvNQHoCQhkmKxuU1d6HFXi3L1lTyWsN4Sbgn8mr8HTK2HhdMPkkMdwk4pOIFvaNVjWBpe4/tH/8YAUjI7JbA==
"@tiptap/core@^2.0.0-beta.41", "@tiptap/core@^2.0.0-beta.84":
version "2.0.0-beta.84"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.84.tgz#71d4f6b1d3c9ba44da7a285950b8b56c7fbd6866"
integrity sha512-wf3qax8/sstXSBsCxnxNCccuKH2vfzz+sozMjaFDvZDjlvItKeYHZ9jVnK9Cv3zuFfCVajJ9zt4+qdcjXB+q2A==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-inputrules" "^1.0.4"
@ -1499,7 +1499,7 @@
prosemirror-commands "^1.1.9"
prosemirror-inputrules "^1.1.3"
prosemirror-keymap "^1.1.3"
prosemirror-model "^1.14.1"
prosemirror-model "^1.14.2"
prosemirror-schema-list "^1.1.4"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.2"
@ -1630,11 +1630,11 @@
integrity sha512-5nvrCvcV35J6WjLd8xQCQWnj2HIDsfTalr0D57jMwym3ZCIEvLwf23DQQ1nNsOHhopmS/Emixh+RQpXUZjH8lQ==
"@tiptap/extension-mention@^2.0.0-beta.42":
version "2.0.0-beta.59"
resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-2.0.0-beta.59.tgz#5fde39a68c1c3c8c896fa28b9dfa4b8448ec340a"
integrity sha512-qwIc/KBjS0/8ZHoV7WJaKSU8VRtX+GDdIksvrPaw+C2k2l7E7KWyi7SxYtu1+cFP27Ob1pCWiwD5Yv/x/wVEVg==
version "2.0.0-beta.60"
resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-2.0.0-beta.60.tgz#9b062b45c22bc659cde7ae5ac9b612cce1fc9678"
integrity sha512-Tk7HbQ21R9cH/Je74mbgeLNkQn97j9G8+oblXY/B2RWawhUMVqlSDM8YogCzU6e6PKJ+mww5o9rta7Npw0jjVw==
dependencies:
"@tiptap/suggestion" "^2.0.0-beta.57"
"@tiptap/suggestion" "^2.0.0-beta.58"
"@tiptap/extension-ordered-list@^2.0.0-beta.14", "@tiptap/extension-ordered-list@^2.0.0-beta.6":
version "2.0.0-beta.14"
@ -1664,11 +1664,11 @@
integrity sha512-xrdNYXBuDaiKBByAuJ8Z9g+1w4I1pp8Id6ZbhxnljiTIwtX6SD/Pp4z/4dKhXNSpHvipyaFEXY0CVpxzbSEk5w==
"@tiptap/starter-kit@^2.0.0-beta.37":
version "2.0.0-beta.79"
resolved "https://registry.yarnpkg.com/@tiptap/starter-kit/-/starter-kit-2.0.0-beta.79.tgz#4c8fdccefe3e4b1dcb6576280c1cfb2320673a71"
integrity sha512-Te0+SkrwgOYl8/fxb+2zBzzBsqtAftYipvMtNOzi94khQEWC7bZs1voJWpmVRZX6dG0vQBpZxVL0wVsFLQTAkg==
version "2.0.0-beta.80"
resolved "https://registry.yarnpkg.com/@tiptap/starter-kit/-/starter-kit-2.0.0-beta.80.tgz#eaa3a683b59c5f8805c82d00af4f4c4eadeadbdb"
integrity sha512-ly4LFofIfkmbJh/EemAZM1s5GXBLju7+WER8UiHFAyRJ7ktl0Q/l2lny35JcK5fWHWR8W1mH50HOCgR0GkIrxw==
dependencies:
"@tiptap/core" "^2.0.0-beta.83"
"@tiptap/core" "^2.0.0-beta.84"
"@tiptap/extension-blockquote" "^2.0.0-beta.14"
"@tiptap/extension-bold" "^2.0.0-beta.14"
"@tiptap/extension-bullet-list" "^2.0.0-beta.14"
@ -1688,12 +1688,12 @@
"@tiptap/extension-strike" "^2.0.0-beta.16"
"@tiptap/extension-text" "^2.0.0-beta.12"
"@tiptap/suggestion@^2.0.0-beta.57":
version "2.0.0-beta.57"
resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.0.0-beta.57.tgz#7da90521098a323bfc55ad380a06599a566d027f"
integrity sha512-dZKwo7zGTCV1wH5M5k/ZhDIIs1cJgxK48scddxu/Ine6ZlGCQyFdUYFkhhiS8eC5Z4Mkgixogr60AfJ/g+Tu1Q==
"@tiptap/suggestion@^2.0.0-beta.58":
version "2.0.0-beta.58"
resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.0.0-beta.58.tgz#a199fa20fabab24f019ffc569e13a11fcf417feb"
integrity sha512-Z8DUiFPPAJ33gN63ZmypSdCtfu1p41xQf36wJiWzGB/s9GaV1dw/lWC+hf0gU7PCN8RW3+SAtAQz8xO2Y/fCHg==
dependencies:
prosemirror-model "^1.14.1"
prosemirror-model "^1.14.2"
prosemirror-state "^1.3.4"
prosemirror-view "^1.18.7"
@ -1936,9 +1936,9 @@
integrity sha512-6nlq2eEh75JegDGUXis9wGTYIJpUvbori4qx++PRKQsV3YRkaqUNPNykzphniqPSZADXCouBuAnyptjUkMkhvw==
"@types/node@*":
version "15.12.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d"
integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==
version "15.12.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.3.tgz#2817bf5f25bc82f56579018c53f7d41b1830b1af"
integrity sha512-SNt65CPCXvGNDZ3bvk1TQ0Qxoe3y1RKH88+wZ2Uf05dduBCqqFQ76ADP9pbT+Cpvj60SkRppMCh2Zo8tDixqjQ==
"@types/node@^14.14.31":
version "14.17.3"
@ -2113,13 +2113,6 @@
dependencies:
source-map "^0.6.1"
"@types/vuedraggable@^2.23.0":
version "2.24.0"
resolved "https://registry.yarnpkg.com/@types/vuedraggable/-/vuedraggable-2.24.0.tgz#f09e8d772c6021b87bc13898fd1183fb81674a61"
integrity sha512-QdR7Vi36ga+cjlILUWVxUBERCRWDoNbjvnWJ6SzoxPlPJUQaY1XjBprF4aH4CI/xSch8TJg5x3rjgTLlt85rew==
dependencies:
vuedraggable "*"
"@types/webpack-dev-server@^3.11.0":
version "3.11.4"
resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.11.4.tgz#90d47dd660b696d409431ab8c1e9fa3615103a07"
@ -3287,12 +3280,12 @@ babel-plugin-polyfill-corejs2@^0.2.2:
semver "^6.1.1"
babel-plugin-polyfill-corejs3@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5"
integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==
version "0.2.3"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz#72add68cf08a8bf139ba6e6dfc0b1d504098e57b"
integrity sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.2.2"
core-js-compat "^3.9.1"
core-js-compat "^3.14.0"
babel-plugin-polyfill-regenerator@^0.2.2:
version "0.2.2"
@ -3658,9 +3651,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001230:
version "1.0.30001237"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz#4b7783661515b8e7151fc6376cfd97f0e427b9e5"
integrity sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw==
version "1.0.30001238"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001238.tgz#e6a8b45455c5de601718736d0242feef0ecdda15"
integrity sha512-bZGam2MxEt7YNsa2VwshqWQMwrYs5tR5WZQRYSuFxsBQunWjBuXhN4cS9nV5FFb1Z9y+DoQcQ0COyQbv6A+CKw==
capture-exit@^2.0.0:
version "2.0.0"
@ -4112,7 +4105,7 @@ copy-webpack-plugin@^8.0.0:
schema-utils "^3.0.0"
serialize-javascript "^5.0.1"
core-js-compat@^3.14.0, core-js-compat@^3.8.3, core-js-compat@^3.9.1:
core-js-compat@^3.14.0, core-js-compat@^3.8.3:
version "3.14.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.14.0.tgz#b574dabf29184681d5b16357bd33d104df3d29a5"
integrity sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A==
@ -5839,9 +5832,9 @@ globals@^13.6.0, globals@^13.9.0:
type-fest "^0.20.2"
globby@^11.0.2, globby@^11.0.3:
version "11.0.3"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
version "11.0.4"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
@ -8923,9 +8916,9 @@ postcss@^7.0.36:
supports-color "^6.1.0"
postcss@^8.2.15, postcss@^8.2.6, postcss@^8.2.9:
version "8.3.4"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.4.tgz#41ece1c43f2f7c74dc7d90144047ce052757b822"
integrity sha512-/tZY0PXExXXnNhKv3TOvZAOUYRyuqcCbBm2c17YMDK0PlVII3K7/LKdt3ScHL+hhouddjUWi+1sKDf9xXW+8YA==
version "8.3.5"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709"
integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==
dependencies:
colorette "^1.2.2"
nanoid "^3.1.23"
@ -9106,7 +9099,7 @@ prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.3:
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.14.1:
prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.14.2:
version "1.14.2"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.14.2.tgz#4e8c39cfff4e097631af4495e125d9a8a9773116"
integrity sha512-TwkACyEiSi8FJiRhg2ffbzmQRy5DR+aTwAr7trNQNZL24HJR8ouxy4qCkG99PnWK0xZ0AjSMtPXSU6hnxAiP7Q==
@ -9594,9 +9587,9 @@ rollup-plugin-terser@^7.0.0:
terser "^5.0.0"
rollup@^2.43.1:
version "2.52.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.52.0.tgz#9df3de6028fae79569a985942b81110205a5a411"
integrity sha512-lSkBDGsVoXjqaBf7dsHwxBJz+p+hJEP72P+LOitA0yVs+Nzxj76FidkZE2thrmhjwGqLYiJo39opi7mAfaQ/Vg==
version "2.52.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.52.1.tgz#dd1cc178d70cf35c48d943fc06fdc32d546e6876"
integrity sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w==
optionalDependencies:
fsevents "~2.3.2"
@ -10638,9 +10631,9 @@ ts-invariant@^0.4.0:
tslib "^1.9.3"
ts-invariant@^0.7.0:
version "0.7.3"
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.7.3.tgz#13aae22a4a165393aaf5cecdee45ef4128d358b8"
integrity sha512-UWDDeovyUTIMWj+45g5nhnl+8oo+GhxL5leTaHn5c8FkQWfh8v66gccLd2/YzVmV5hoQUjCEjhrXnQqVDJdvKA==
version "0.7.5"
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.7.5.tgz#f9658719f9a7737b117d09820d952aacf6263f9c"
integrity sha512-qfVyqTYWEqADMtncLqwpUdMjMSXnsqOeqGtj1LeJNFDjz8oqZ1YxLEp29YCOq65z0LgEiERqQ8ThVjnfibJNpg==
dependencies:
tslib "^2.1.0"
@ -10770,14 +10763,14 @@ typedarray-to-buffer@^3.1.5:
is-typedarray "^1.0.0"
typescript@^3.9.3:
version "3.9.9"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674"
integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==
version "3.9.10"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
typescript@~4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72"
integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==
version "4.1.6"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.6.tgz#1becd85d77567c3c741172339e93ce2e69932138"
integrity sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow==
unbox-primitive@^1.0.1:
version "1.0.1"
@ -11122,7 +11115,7 @@ vue@^2.6.11:
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.14.tgz#e51aa5250250d569a3fbad3a8a5a687d6036e235"
integrity sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==
vuedraggable@*, vuedraggable@^2.24.3:
vuedraggable@^2.24.3:
version "2.24.3"
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==
@ -11322,9 +11315,9 @@ webpack-virtual-modules@^0.4.2:
integrity sha512-5NUqC2JquIL2pBAAo/VfBP6KuGkHIZQXW/lNKupLPfhViwh8wNsu0BObtl09yuKZszeEUfbXz8xhrHvSG16Nqw==
webpack@^5.22.0:
version "5.39.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.39.0.tgz#37d6899f1f40c31d5901abc0f39bc8cc7224138c"
integrity sha512-25CHmuDj+oOTyteI13sUqNlCnjCnySuhiKWE/cRYPQYeoQ3ijHgyWX27CiyUKLNGq27v8S0mrksyTreT/xo7pg==
version "5.39.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.39.1.tgz#d1e014b6d71e1aef385316ad528f21cd5b1f9784"
integrity sha512-ulOvoNCh2PvTUa+zbpRuEb1VPeQnhxpnHleMPVVCq3QqnaFogjsLyps+o42OviQFoaGtTQYrUqDXu1QNkvUPzw==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.47"
@ -11651,9 +11644,9 @@ ws@^6.2.1:
async-limiter "~1.0.0"
ws@^7.3.1, ws@^7.4.5:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
version "7.5.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.0.tgz#0033bafea031fb9df041b2026fc72a571ca44691"
integrity sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==
xml-name-validator@^3.0.0:
version "3.0.0"