diff --git a/package.json b/package.json index 8bc8d3ad9..a2cf25dd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "automa", - "version": "1.21.1", + "version": "1.21.2", "description": "An extension for automating your browser by connecting blocks", "repository": { "type": "git", @@ -31,7 +31,7 @@ "@braks/vue-flow": "^0.4.40", "@codemirror/autocomplete": "^6.1.0", "@codemirror/lang-css": "^6.0.0", - "@codemirror/lang-html": "^6.1.0", + "@codemirror/lang-html": "^6.1.2", "@codemirror/lang-javascript": "^6.0.2", "@codemirror/lang-json": "^6.0.0", "@codemirror/language": "^6.2.1", @@ -43,11 +43,11 @@ "@tiptap/extension-placeholder": "^2.0.0-beta.53", "@tiptap/starter-kit": "^2.0.0-beta.197", "@tiptap/vue-3": "^2.0.0-beta.96", - "@viselect/vanilla": "^3.1.0", + "@viselect/vanilla": "^3.1.1", "@vueuse/rxjs": "^9.1.1", "@vuex-orm/core": "^0.36.4", "codemirror": "^6.0.1", - "compare-versions": "^4.1.2", + "compare-versions": "^5.0.1", "cron-parser": "^4.6.0", "cronstrue": "^2.11.0", "crypto-js": "^4.1.1", @@ -106,7 +106,7 @@ "eslint-plugin-vue": "^9.4.0", "file-loader": "^6.2.0", "fs-extra": "^10.1.0", - "html-loader": "^4.1.0", + "html-loader": "^4.2.0", "html-webpack-plugin": "^5.5.0", "lint-staged": "^13.0.2", "mini-css-extract-plugin": "^2.3.0", @@ -121,6 +121,6 @@ "web-worker": "^1.2.0", "webpack": "^5.73.0", "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.11.0" + "webpack-dev-server": "^4.11.1" } } diff --git a/src/background/workflowEngine/blocksHandler/handlerLoopData.js b/src/background/workflowEngine/blocksHandler/handlerLoopData.js index 74f8bf4df..59b5fb26c 100644 --- a/src/background/workflowEngine/blocksHandler/handlerLoopData.js +++ b/src/background/workflowEngine/blocksHandler/handlerLoopData.js @@ -49,6 +49,7 @@ async function loopData({ data, id }, { refData }) { findBy, max: maxLoop, multiple: true, + reverseLoop: data.reverseLoop, selector: data.elementSelector, waitForSelector: data.waitForSelector ?? false, waitSelectorTimeout: data.waitSelectorTimeout ?? 5000, @@ -81,7 +82,7 @@ async function loopData({ data, id }, { refData }) { index = data.startIndex; } - if (data.reverseLoop) { + if (data.reverseLoop && data.loopThrough !== 'elements') { currLoopData.reverse(); } } diff --git a/src/components/newtab/workflow/edit/EditElementExists.vue b/src/components/newtab/workflow/edit/EditElementExists.vue index 173103bdc..a49ceb8f4 100644 --- a/src/components/newtab/workflow/edit/EditElementExists.vue +++ b/src/components/newtab/workflow/edit/EditElementExists.vue @@ -20,8 +20,8 @@ diff --git a/src/components/newtab/workflow/edit/EditLoopElements.vue b/src/components/newtab/workflow/edit/EditLoopElements.vue index 7c6e02394..1dbb1893a 100644 --- a/src/components/newtab/workflow/edit/EditLoopElements.vue +++ b/src/components/newtab/workflow/edit/EditLoopElements.vue @@ -21,6 +21,13 @@ class="w-full mt-3" @change="updateData({ maxLoop: $event })" /> + + {{ t('workflow.blocks.loop-data.reverse') }} +

{{ t('workflow.blocks.loop-elements.loadMore') }} diff --git a/src/content/commandPalette/App.vue b/src/content/commandPalette/App.vue index 32f7b5a1c..6eb08a6de 100644 --- a/src/content/commandPalette/App.vue +++ b/src/content/commandPalette/App.vue @@ -248,9 +248,10 @@ function onKeydown(event) { return; } - if (state.shortcutKeys.length < 1) return; + const shortcuts = window._automaShortcuts; + if (shortcuts.length < 1) return; - const automaShortcut = state.shortcutKeys.every((shortcutKey) => { + const automaShortcut = shortcuts.every((shortcutKey) => { if (shortcutKey === 'mod') return ctrlKey || metaKey; if (shortcutKey === 'shift') return shiftKey; if (shortcutKey === 'option') return altKey; @@ -260,6 +261,7 @@ function onKeydown(event) { if (automaShortcut) { event.preventDefault(); state.active = true; + state.shortcutKeys = shortcuts; } } function onInputKeydown(event) { @@ -385,10 +387,11 @@ onMounted(() => { browser.storage.local.get('automaShortcut').then(({ automaShortcut }) => { if (Array.isArray(automaShortcut) && automaShortcut.length < 1) return; - let keys = ['mod', 'shift', 'a']; + let keys = ['mod', 'shift', 'e']; if (automaShortcut) keys = automaShortcut.split('+'); state.shortcutKeys = keys; + window._automaShortcuts = keys; }); window.addEventListener('keydown', onKeydown); diff --git a/src/content/index.js b/src/content/index.js index 9bf79b5a2..805db2b12 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -42,8 +42,7 @@ function messageToFrame(frameElement, blockData) { } async function executeBlock(data) { const removeExecutedBlock = showExecutedBlock(data, data.executedBlockOnWeb); - - if (data.data?.selector?.includes('|>') && isMainFrame) { + if (data.data?.selector?.includes('|>')) { const [frameSelector, selector] = data.data.selector.split(/\|>(.+)/); const frameElement = document.querySelector(frameSelector); const frameError = (message) => { @@ -136,18 +135,41 @@ function messageListener({ data, source }) { initCommandPalette(); + let contextElement = null; + let $ctxLink = ''; + let $ctxMediaUrl = ''; + let $ctxTextSelection = ''; + window.isAutomaInjected = true; window.addEventListener('message', messageListener); + window.addEventListener( + 'contextmenu', + ({ target }) => { + contextElement = target; + $ctxTextSelection = window.getSelection().toString(); - let contextElement = null; - let $ctxTextSelection = ''; + const tag = target.tagName; + if (tag === 'A') { + $ctxLink = target.href; + } + + const mediaTags = ['AUDIO', 'VIDEO', 'IMG']; + if (mediaTags.includes(tag)) { + let mediaSrc = target.src || ''; + + if (!mediaSrc.src) { + const sourceEl = target.querySelector('source'); + if (sourceEl) mediaSrc = sourceEl.src; + } + + $ctxMediaUrl = mediaSrc; + } + }, + true + ); if (isMainFrame) { shortcutListener(); - window.addEventListener('contextmenu', ({ target }) => { - contextElement = target; - $ctxTextSelection = window.getSelection().toString(); - }); // window.addEventListener('load', elementObserver); } @@ -198,30 +220,10 @@ function messageListener({ data, source }) { break; } case 'context-element': { - let $ctxLink = ''; - let $ctxMediaUrl = ''; let $ctxElSelector = ''; if (contextElement) { $ctxElSelector = findSelector(contextElement); - - const tag = contextElement.tagName; - if (tag === 'A') { - $ctxLink = contextElement.href; - } - - const mediaTags = ['AUDIO', 'VIDEO', 'IMG']; - if (mediaTags.includes(tag)) { - let mediaSrc = contextElement.src || ''; - - if (!mediaSrc.src) { - const sourceEl = contextElement.querySelector('source'); - if (sourceEl) mediaSrc = sourceEl.src; - } - - $ctxMediaUrl = mediaSrc; - } - contextElement = null; } if (!$ctxTextSelection) { @@ -229,10 +231,10 @@ function messageListener({ data, source }) { } resolve({ - $ctxElSelector, - $ctxTextSelection, $ctxLink, $ctxMediaUrl, + $ctxElSelector, + $ctxTextSelection, }); break; } diff --git a/src/content/services/shortcutListener.js b/src/content/services/shortcutListener.js index d18df7464..fbf96721a 100644 --- a/src/content/services/shortcutListener.js +++ b/src/content/services/shortcutListener.js @@ -63,20 +63,28 @@ function workflowShortcutsListener(findWorkflow, shortcutsObj) { return true; }); } +async function getWorkflows() { + const { workflows, workflowHosts } = await browser.storage.local.get([ + 'workflows', + 'workflowHosts', + ]); + const localWorkflows = Array.isArray(workflows) + ? workflows + : Object.values(workflows); + + return { + local: localWorkflows, + hosted: Object.values(workflowHosts || {}), + }; +} export default async function () { try { - const { shortcuts, workflows, workflowHosts } = - await browser.storage.local.get([ - 'shortcuts', - 'workflows', - 'workflowHosts', - ]); - const workflowsArr = Array.isArray(workflows) - ? workflows - : Object.values(workflows); + const storage = await browser.storage.local.get('shortcuts'); + let workflows = await getWorkflows(); + const findWorkflow = (id, publicId = false) => { - let workflow = workflowsArr.find((item) => { + let workflow = workflows.local.find((item) => { if (publicId) { return item.settings.publicId === id; } @@ -85,9 +93,7 @@ export default async function () { }); if (!workflow) { - workflow = Object.values(workflowHosts || {}).find( - ({ hostId }) => hostId === id - ); + workflow = workflows.hosted.find(({ hostId }) => hostId === id); if (workflow) workflow.id = workflow.hostId; } @@ -95,8 +101,30 @@ export default async function () { return workflow; }; + browser.storage.onChanged.addListener(({ automaShortcut, shortcuts }) => { + if (automaShortcut) { + if ( + Array.isArray(automaShortcut.newValue) && + automaShortcut.newValue.length < 1 + ) { + window._automaShortcuts = []; + } else { + const automaShortcutArr = automaShortcut.newValue.split('+'); + + window._automaShortcuts = automaShortcutArr; + } + } + if (shortcuts) { + Mousetrap.reset(); + getWorkflows().then((updatedWorkflows) => { + workflows = updatedWorkflows; + workflowShortcutsListener(findWorkflow, shortcuts.newValue || {}); + }); + } + }); + automaCustomEventListener(findWorkflow); - workflowShortcutsListener(findWorkflow, shortcuts || {}); + workflowShortcutsListener(findWorkflow, storage.shortcuts || {}); } catch (error) { console.error(error); } diff --git a/src/content/utils.js b/src/content/utils.js index 8a6ff1562..6448301b6 100644 --- a/src/content/utils.js +++ b/src/content/utils.js @@ -13,11 +13,16 @@ export function simulateClickElement(element) { export function generateLoopSelectors( elements, - { max, attrId, frameSelector, startIndex = 0 } + { max, attrId, frameSelector, reverseLoop, startIndex = 0 } ) { const selectors = []; + let elementsList = elements; - elements.forEach((el, index) => { + if (reverseLoop) { + elementsList = Array.from(elements).reverse(); + } + + elementsList.forEach((el, index) => { if (max > 0 && selectors.length - 1 > max) return; const attrName = 'automa-loop'; diff --git a/src/newtab/pages/settings/SettingsShortcuts.vue b/src/newtab/pages/settings/SettingsShortcuts.vue index 9df4822d8..6825cda58 100644 --- a/src/newtab/pages/settings/SettingsShortcuts.vue +++ b/src/newtab/pages/settings/SettingsShortcuts.vue @@ -108,7 +108,7 @@ const { t } = useI18n(); const toast = useToast(); const shortcuts = ref(mapShortcuts); -const automaShortcut = ref(getReadableShortcut('mod+shift+a')); +const automaShortcut = ref(getReadableShortcut('mod+shift+e')); const recording = reactive({ id: '', keys: [], diff --git a/src/utils/shared.js b/src/utils/shared.js index ba03f0d76..1cc07d7f3 100644 --- a/src/utils/shared.js +++ b/src/utils/shared.js @@ -742,11 +742,12 @@ export const tasks = { data: { disableBlock: false, loopId: '', + selector: '', maxLoop: '0', description: '', - selector: '', - findBy: 'cssSelector', + reverseLoop: false, actionElSelector: '', + findBy: 'cssSelector', actionElMaxWaitTime: 5, actionPageMaxWaitTime: 10, loadMoreAction: 'none', @@ -1241,7 +1242,7 @@ export const tasks = { outputs: 1, allowedInputs: true, maxConnection: 1, - refDataKeys: ['html', 'css'], + refDataKeys: ['html', 'css', 'selector'], data: { disableBlock: false, description: '', diff --git a/src/utils/workflowTrigger.js b/src/utils/workflowTrigger.js index 4ec04b914..55c7b4b61 100644 --- a/src/utils/workflowTrigger.js +++ b/src/utils/workflowTrigger.js @@ -3,7 +3,7 @@ import dayjs from 'dayjs'; import cronParser from 'cron-parser'; import { isObject } from './helper'; -export function registerContextMenu(workflowId, data) { +export function registerContextMenu(triggerId, data) { return new Promise((resolve, reject) => { const documentUrlPatterns = ['https://*/*', 'http://*/*']; const contextTypes = @@ -19,6 +19,10 @@ export function registerContextMenu(workflowId, data) { return; } + const workflowId = triggerId.includes(':') + ? triggerId.split(':')[1] + : triggerId; + browserContext.create( { id: workflowId, @@ -29,7 +33,6 @@ export function registerContextMenu(workflowId, data) { }, () => { const error = browser.runtime.lastError; - if (error) { if (error.message.includes('automaContextMenu')) { browserContext.create( @@ -45,6 +48,13 @@ export function registerContextMenu(workflowId, data) { .catch(reject); } ); + resolve(); + return; + } + if (error.message.includes('Duplicate id')) { + browserContext.remove(triggerId).then(() => { + registerContextMenu(workflowId, data).then(resolve).catch(reject); + }); return; } @@ -71,7 +81,7 @@ async function removeFromWorkflowQueue(workflowId) { await browser.storage.local.set({ workflowQueue }); } -export async function cleanWorkflowTriggers(workflowId) { +export async function cleanWorkflowTriggers(workflowId, triggers) { try { const alarms = await browser.alarms.getAll(); for (const alarm of alarms) { @@ -109,17 +119,29 @@ export async function cleanWorkflowTriggers(workflowId) { visitWebTriggers: filteredVisitWebTriggers, }); + const browserContextMenu = + BROWSER_TYPE === 'firefox' ? browser.menus : browser.contextMenus; const removeFromContextMenu = async () => { try { - await (BROWSER_TYPE === 'firefox' - ? browser.menus - : browser.contextMenus - )?.remove(workflowId); + let promises = []; + + if (triggers) { + promises = triggers.map(async (trigger) => { + if (trigger.type !== 'context-menu') return; + + const triggerId = `trigger:${workflowId}:${trigger.id}`; + await browserContextMenu.remove(triggerId); + }); + } + + promises.push(browserContextMenu.remove(workflowId)); + + await Promise.allSettled(promises); } catch (error) { // Do nothing } }; - await removeFromContextMenu(); + if (browserContextMenu) await removeFromContextMenu(); } catch (error) { console.error(error); } @@ -259,7 +281,7 @@ export const workflowTriggersMap = { export async function registerWorkflowTrigger(workflowId, { data }) { try { - await cleanWorkflowTriggers(workflowId); + await cleanWorkflowTriggers(workflowId, data.triggers); if (data.triggers) { for (const trigger of data.triggers) { diff --git a/yarn.lock b/yarn.lock index 7595bbd8b..7d23c700d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -952,10 +952,10 @@ "@codemirror/state" "^6.0.0" "@lezer/css" "^1.0.0" -"@codemirror/lang-html@^6.1.0": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-6.1.1.tgz#1bbe5ac2b5af113594bf99ee8c85399bfcf42349" - integrity sha512-+hV1kVZySmr7GxCgSVM+BodaVlsgD98laEJbj/GALhgIrfnHTSiRuTz2EPTjNCKeq5uEQXeOKFY711/CxJbYrg== +"@codemirror/lang-html@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-6.1.2.tgz#64979e583c6120c70d3123e6ce3f8595b20abc52" + integrity sha512-e8JAUWyOo7N26tmek+WK0+Zg+pZRe+dQi8TZq0OOVVygpLV+mNAT2n5b5JhknY+TVZIVGLjuhdsoizw1SDFfPg== dependencies: "@codemirror/autocomplete" "^6.0.0" "@codemirror/lang-css" "^6.0.0" @@ -1674,10 +1674,10 @@ dependencies: "@types/node" "*" -"@viselect/vanilla@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@viselect/vanilla/-/vanilla-3.1.0.tgz#66ef6eaa383a053c24bd2f6d8db1691f5b32e6bb" - integrity sha512-B0cvgsHandCXXsqp3O09HKR6buJa6kGpzu/Y9gQOiKcE26mbfRlZIGKBcYEdOELmRa+QrzG6ydegjNET/htsGg== +"@viselect/vanilla@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@viselect/vanilla/-/vanilla-3.1.1.tgz#e63ef3529f819cc83e8c1aea6b3ab9936d550f76" + integrity sha512-aS1UF6WkV3TvO5vqg2uQk8WRI36b2SAtfozVrxtfVI1WTuaOG0uYxvdXTmIYwfki6fFF4qQpkiQcg8+NqpJA8Q== "@vue/compiler-core@3.2.39": version "3.2.39" @@ -2486,6 +2486,13 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== +clean-css@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.0.tgz#44e4a04e8873ff0041df97acecf23a4a6519844e" + integrity sha512-2639sWGa43EMmG7fn8mdVuBSs6HuWaSor+ZPoFWzenBc6oN+td8YhTfghWXZ25G1NiiSvz8bOFBS7PdSbTiqEA== + dependencies: + source-map "~0.6.0" + clean-css@^5.2.2: version "5.3.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" @@ -2604,15 +2611,20 @@ commander@^9.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== +commander@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" + integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== -compare-versions@^4.1.2: - version "4.1.4" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-4.1.4.tgz#3571f4d610924d4414846a4183d386c8f3d51112" - integrity sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw== +compare-versions@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.1.tgz#14c6008436d994c3787aba38d4087fabe858555e" + integrity sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ== compress-commons@^4.1.0: version "4.1.1" @@ -3166,7 +3178,7 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^4.4.0: +entities@^4.3.1, entities@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== @@ -3996,15 +4008,15 @@ html-entities@^2.3.2: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== -html-loader@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-4.1.0.tgz#a2f935802675fef0703165491316b200600996be" - integrity sha512-QDDNmLgn96NWtTPx/VXRerFXH0hn7cm4bruqsZ333GCb+rqiqGurcxtP/M52wcui1/iLiu0l5ms/McE7/Ik6aQ== +html-loader@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-4.2.0.tgz#20f69f9ec69244860c250ae6ee0046c8c5c4d348" + integrity sha512-OxCHD3yt+qwqng2vvcaPApCEvbx+nXWu+v69TYHx1FO8bffHn/JjHtE3TTQZmHjwvnJe4xxzuecetDVBrQR1Zg== dependencies: - html-minifier-terser "^6.1.0" + html-minifier-terser "^7.0.0" parse5 "^7.0.0" -html-minifier-terser@^6.0.2, html-minifier-terser@^6.1.0: +html-minifier-terser@^6.0.2: version "6.1.0" resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== @@ -4017,6 +4029,19 @@ html-minifier-terser@^6.0.2, html-minifier-terser@^6.1.0: relateurl "^0.2.7" terser "^5.10.0" +html-minifier-terser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-7.0.0.tgz#e0ce8f10befeff89f29f19490f87213b85adaa4c" + integrity sha512-Adqk0b/pWKIQiGvEAuzPKpBKNHiwblr3QSGS7TTr6v+xXKV9AI2k4vWW+6Oytt6Z5SeBnfvYypKOnz8r75pz3Q== + dependencies: + camel-case "^4.1.2" + clean-css "5.2.0" + commander "^9.4.0" + entities "^4.3.1" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.14.2" + html-webpack-plugin@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" @@ -5831,7 +5856,7 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.0.1: +selfsigned@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== @@ -6281,6 +6306,16 @@ terser@^5.10.0, terser@^5.14.1: commander "^2.20.0" source-map-support "~0.5.20" +terser@^5.14.2: + version "5.15.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.1.tgz#8561af6e0fd6d839669c73b92bdd5777d870ed6c" + integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + text-segmentation@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943" @@ -6625,10 +6660,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.11.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz#290ee594765cd8260adfe83b2d18115ea04484e7" - integrity sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw== +webpack-dev-server@^4.11.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -6653,7 +6688,7 @@ webpack-dev-server@^4.11.0: p-retry "^4.5.0" rimraf "^3.0.2" schema-utils "^4.0.0" - selfsigned "^2.0.1" + selfsigned "^2.1.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2"