From 3eca34cdcfa8c5a4f8de73cff7f65e4a971d6612 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 12:26:35 -0300 Subject: [PATCH 01/11] v1 of storing DOM changes --- apps/mocksi-lite/consts.ts | 1 + apps/mocksi-lite/content/content.tsx | 5 ++++ apps/mocksi-lite/utils.ts | 44 +++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/apps/mocksi-lite/consts.ts b/apps/mocksi-lite/consts.ts index 4f9cc661..c91e0b9a 100644 --- a/apps/mocksi-lite/consts.ts +++ b/apps/mocksi-lite/consts.ts @@ -1,4 +1,5 @@ export const MOCKSI_RECORDING_STATE = "mocksi-recordingState"; +export const MOCKSI_MODIFICATIONS = "mocksi-modifications" export const COOKIE_NAME = "sessionid"; export enum RecordingState { diff --git a/apps/mocksi-lite/content/content.tsx b/apps/mocksi-lite/content/content.tsx index 4a099db6..423ccc40 100644 --- a/apps/mocksi-lite/content/content.tsx +++ b/apps/mocksi-lite/content/content.tsx @@ -1,5 +1,6 @@ import ReactDOM from "react-dom/client"; import ContentApp from "./ContentApp"; +import { loadModifications, saveModification } from "../utils"; let root: ReactDOM.Root; @@ -127,11 +128,14 @@ function elementWithBorder( const selectedText = document.getElementById("mocksiSelectedText"); // @ts-ignore I don't know why the value property is no inside the target object const newValue = event.target?.value; + debugger const parentElement = selectedText?.parentElement; + const previousText = selectedText?.parentElement?.innerText selectedText?.parentElement?.replaceChild( document.createTextNode(newValue), selectedText, ); + saveModification(parentElement, parentElement?.innerHTML || parentElement?.innerText) parentElement?.normalize(); }; @@ -178,6 +182,7 @@ document.addEventListener("DOMContentLoaded", initial); export const setEditorMode = (turnOn: boolean) => { if (turnOn) { + loadModifications() document.body.addEventListener("dblclick", onDoubleClickText); } else { document.body.removeEventListener("dblclick", onDoubleClickText); diff --git a/apps/mocksi-lite/utils.ts b/apps/mocksi-lite/utils.ts index 49d68c18..2d18ff81 100644 --- a/apps/mocksi-lite/utils.ts +++ b/apps/mocksi-lite/utils.ts @@ -1,4 +1,5 @@ -import { COOKIE_NAME, MOCKSI_RECORDING_STATE, RecordingState } from "./consts"; +import { COOKIE_NAME, MOCKSI_MODIFICATIONS, MOCKSI_RECORDING_STATE, RecordingState } from "./consts"; + export const setRootPosition = (state: RecordingState) => { const extensionRoot = document.getElementById("extension-root"); @@ -13,3 +14,44 @@ export const logout = () => { document.cookie = `${COOKIE_NAME}=`; localStorage.setItem(MOCKSI_RECORDING_STATE, RecordingState.UNAUTHORIZED); }; + + +//@ts-ignore +export const saveModification = (parentElement: any, newText: any) => { + const prevModifications = JSON.parse(localStorage.getItem(MOCKSI_MODIFICATIONS) || '{}') + let keyToSave = parentElement.localName + if (parentElement.id) { + keyToSave += `#${parentElement.id}` + } + if (parentElement.className) { + keyToSave += `.${parentElement.className}` + } + const elements = document.querySelectorAll(keyToSave) + if (elements.length == 1) { + // keyToSave += `-${previousText}` + console.log(keyToSave, newText) + localStorage.setItem(MOCKSI_MODIFICATIONS, JSON.stringify({ ...prevModifications, [keyToSave] : newText })) + } else { + // const elementIndex = [...elements].indexOf(parentElement) + keyToSave += `[${[...elements].indexOf(parentElement)}]` + localStorage.setItem(MOCKSI_MODIFICATIONS, JSON.stringify({ ...prevModifications, [keyToSave] : newText })) + } +} + +export const loadModifications = () => { + const modifications = JSON.parse(localStorage.getItem(MOCKSI_MODIFICATIONS) || '{}') + Object.entries(modifications).forEach( ([querySelector, value]) => { + const hasIndex = querySelector.match(/\[+[0-9]\]/) + if (hasIndex) { + const index: number = +hasIndex[0].replace('[', '').replace(']', '') + const elemToModify = document.querySelectorAll(querySelector.replace(hasIndex[0], ''))[index] + //@ts-ignore EXTREMELY INSECURE!!!!!!!! + elemToModify.innerHTML = value + } else { + const [elemToModify] = document.querySelectorAll(querySelector) + //@ts-ignore EXTREMELY INSECURE!!!!!!!! + elemToModify.innerHTML = value + } + }) + console.log('loadedModifications!', modifications) +} From f5e87dbeba303522acd93b94e09d836c51f42af5 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 12:27:08 -0300 Subject: [PATCH 02/11] removed unused consts --- apps/mocksi-lite/content/content.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/mocksi-lite/content/content.tsx b/apps/mocksi-lite/content/content.tsx index 423ccc40..e662860f 100644 --- a/apps/mocksi-lite/content/content.tsx +++ b/apps/mocksi-lite/content/content.tsx @@ -128,9 +128,7 @@ function elementWithBorder( const selectedText = document.getElementById("mocksiSelectedText"); // @ts-ignore I don't know why the value property is no inside the target object const newValue = event.target?.value; - debugger const parentElement = selectedText?.parentElement; - const previousText = selectedText?.parentElement?.innerText selectedText?.parentElement?.replaceChild( document.createTextNode(newValue), selectedText, From f1b4ae8d3e94218c7035a72cc0214124acf6ca7d Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 12:42:31 -0300 Subject: [PATCH 03/11] biome fixes --- apps/mocksi-lite/consts.ts | 2 +- apps/mocksi-lite/content/content.tsx | 9 ++-- apps/mocksi-lite/utils.ts | 71 ++++++++++++++++++---------- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/apps/mocksi-lite/consts.ts b/apps/mocksi-lite/consts.ts index c91e0b9a..70b7189c 100644 --- a/apps/mocksi-lite/consts.ts +++ b/apps/mocksi-lite/consts.ts @@ -1,5 +1,5 @@ export const MOCKSI_RECORDING_STATE = "mocksi-recordingState"; -export const MOCKSI_MODIFICATIONS = "mocksi-modifications" +export const MOCKSI_MODIFICATIONS = "mocksi-modifications"; export const COOKIE_NAME = "sessionid"; export enum RecordingState { diff --git a/apps/mocksi-lite/content/content.tsx b/apps/mocksi-lite/content/content.tsx index e662860f..11416681 100644 --- a/apps/mocksi-lite/content/content.tsx +++ b/apps/mocksi-lite/content/content.tsx @@ -1,6 +1,6 @@ import ReactDOM from "react-dom/client"; -import ContentApp from "./ContentApp"; import { loadModifications, saveModification } from "../utils"; +import ContentApp from "./ContentApp"; let root: ReactDOM.Root; @@ -133,7 +133,10 @@ function elementWithBorder( document.createTextNode(newValue), selectedText, ); - saveModification(parentElement, parentElement?.innerHTML || parentElement?.innerText) + saveModification( + parentElement as HTMLElement, + parentElement?.innerHTML || parentElement?.innerText || "", + ); parentElement?.normalize(); }; @@ -180,7 +183,7 @@ document.addEventListener("DOMContentLoaded", initial); export const setEditorMode = (turnOn: boolean) => { if (turnOn) { - loadModifications() + loadModifications(); document.body.addEventListener("dblclick", onDoubleClickText); } else { document.body.removeEventListener("dblclick", onDoubleClickText); diff --git a/apps/mocksi-lite/utils.ts b/apps/mocksi-lite/utils.ts index 2d18ff81..fd50d5e6 100644 --- a/apps/mocksi-lite/utils.ts +++ b/apps/mocksi-lite/utils.ts @@ -1,5 +1,9 @@ -import { COOKIE_NAME, MOCKSI_MODIFICATIONS, MOCKSI_RECORDING_STATE, RecordingState } from "./consts"; - +import { + COOKIE_NAME, + MOCKSI_MODIFICATIONS, + MOCKSI_RECORDING_STATE, + RecordingState, +} from "./consts"; export const setRootPosition = (state: RecordingState) => { const extensionRoot = document.getElementById("extension-root"); @@ -15,43 +19,58 @@ export const logout = () => { localStorage.setItem(MOCKSI_RECORDING_STATE, RecordingState.UNAUTHORIZED); }; - //@ts-ignore -export const saveModification = (parentElement: any, newText: any) => { - const prevModifications = JSON.parse(localStorage.getItem(MOCKSI_MODIFICATIONS) || '{}') - let keyToSave = parentElement.localName +export const saveModification = ( + parentElement: HTMLElement, + newText: string, +) => { + const prevModifications = JSON.parse( + localStorage.getItem(MOCKSI_MODIFICATIONS) || "{}", + ); + let keyToSave = parentElement.localName; if (parentElement.id) { - keyToSave += `#${parentElement.id}` + keyToSave += `#${parentElement.id}`; } if (parentElement.className) { - keyToSave += `.${parentElement.className}` + keyToSave += `.${parentElement.className}`; } - const elements = document.querySelectorAll(keyToSave) - if (elements.length == 1) { + const elements = document.querySelectorAll(keyToSave); + if (elements.length === 1) { // keyToSave += `-${previousText}` - console.log(keyToSave, newText) - localStorage.setItem(MOCKSI_MODIFICATIONS, JSON.stringify({ ...prevModifications, [keyToSave] : newText })) + console.log(keyToSave, newText); + localStorage.setItem( + MOCKSI_MODIFICATIONS, + JSON.stringify({ ...prevModifications, [keyToSave]: newText }), + ); } else { // const elementIndex = [...elements].indexOf(parentElement) - keyToSave += `[${[...elements].indexOf(parentElement)}]` - localStorage.setItem(MOCKSI_MODIFICATIONS, JSON.stringify({ ...prevModifications, [keyToSave] : newText })) + keyToSave += `[${[...elements].indexOf(parentElement)}]`; + localStorage.setItem( + MOCKSI_MODIFICATIONS, + JSON.stringify({ ...prevModifications, [keyToSave]: newText }), + ); } -} +}; export const loadModifications = () => { - const modifications = JSON.parse(localStorage.getItem(MOCKSI_MODIFICATIONS) || '{}') - Object.entries(modifications).forEach( ([querySelector, value]) => { - const hasIndex = querySelector.match(/\[+[0-9]\]/) + const modifications = JSON.parse( + localStorage.getItem(MOCKSI_MODIFICATIONS) || "{}", + ); + for (const modification of Object.entries(modifications)) { + const [querySelector, value] = modification; + const hasIndex = querySelector.match(/\[+[0-9]\]/); if (hasIndex) { - const index: number = +hasIndex[0].replace('[', '').replace(']', '') - const elemToModify = document.querySelectorAll(querySelector.replace(hasIndex[0], ''))[index] + const index: number = +hasIndex[0].replace("[", "").replace("]", ""); + const elemToModify = document.querySelectorAll( + querySelector.replace(hasIndex[0], ""), + )[index]; //@ts-ignore EXTREMELY INSECURE!!!!!!!! - elemToModify.innerHTML = value + elemToModify.innerHTML = value; } else { - const [elemToModify] = document.querySelectorAll(querySelector) + const [elemToModify] = document.querySelectorAll(querySelector); //@ts-ignore EXTREMELY INSECURE!!!!!!!! - elemToModify.innerHTML = value + elemToModify.innerHTML = value; } - }) - console.log('loadedModifications!', modifications) -} + } + console.log("loadedModifications!", modifications); +}; From b12c3a455d4fc6923ac9e0c3fcde0d45e0fe9bf7 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 12:51:48 -0300 Subject: [PATCH 04/11] fixed crash when text is not selected --- apps/mocksi-lite/content/content.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/mocksi-lite/content/content.tsx b/apps/mocksi-lite/content/content.tsx index 11416681..81a2d92b 100644 --- a/apps/mocksi-lite/content/content.tsx +++ b/apps/mocksi-lite/content/content.tsx @@ -161,13 +161,12 @@ function onDoubleClickText(event: MouseEvent) { parentElement?.normalize(); } const targetedElement: HTMLElement = event.target as HTMLElement; - const { startOffset, endOffset } = - window.getSelection()?.getRangeAt(0) || {}; - if (startOffset !== undefined && endOffset !== undefined) { - applyEditor(targetedElement, window.getSelection(), event.shiftKey); + const selection = window.getSelection(); + if (selection?.toString()) { + applyEditor(targetedElement, selection, event.shiftKey); document.getElementById("mocksiTextArea")?.focus(); } else { - console.log("ERROR! no offset detected", targetedElement); + console.log("ERROR! no selection detected", targetedElement); } } } From c2a9f472f03a3c0c9f806ef557c0cf08b117c7cb Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 13:18:52 -0300 Subject: [PATCH 05/11] removed commented code --- apps/mocksi-lite/utils.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/mocksi-lite/utils.ts b/apps/mocksi-lite/utils.ts index fd50d5e6..75f1dfb9 100644 --- a/apps/mocksi-lite/utils.ts +++ b/apps/mocksi-lite/utils.ts @@ -19,7 +19,6 @@ export const logout = () => { localStorage.setItem(MOCKSI_RECORDING_STATE, RecordingState.UNAUTHORIZED); }; -//@ts-ignore export const saveModification = ( parentElement: HTMLElement, newText: string, @@ -36,14 +35,12 @@ export const saveModification = ( } const elements = document.querySelectorAll(keyToSave); if (elements.length === 1) { - // keyToSave += `-${previousText}` console.log(keyToSave, newText); localStorage.setItem( MOCKSI_MODIFICATIONS, JSON.stringify({ ...prevModifications, [keyToSave]: newText }), ); } else { - // const elementIndex = [...elements].indexOf(parentElement) keyToSave += `[${[...elements].indexOf(parentElement)}]`; localStorage.setItem( MOCKSI_MODIFICATIONS, From ada2b6410f3075cfe36f53801620ffce47725873 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 13:56:18 -0300 Subject: [PATCH 06/11] added some comments to explain logic --- apps/mocksi-lite/utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/mocksi-lite/utils.ts b/apps/mocksi-lite/utils.ts index 75f1dfb9..d89c18e3 100644 --- a/apps/mocksi-lite/utils.ts +++ b/apps/mocksi-lite/utils.ts @@ -33,14 +33,15 @@ export const saveModification = ( if (parentElement.className) { keyToSave += `.${parentElement.className}`; } + // here we check if the key we built is sufficient to get an unique element when querying const elements = document.querySelectorAll(keyToSave); if (elements.length === 1) { - console.log(keyToSave, newText); localStorage.setItem( MOCKSI_MODIFICATIONS, JSON.stringify({ ...prevModifications, [keyToSave]: newText }), ); } else { + // if not unique, we search for the index and put it on the key. keyToSave += `[${[...elements].indexOf(parentElement)}]`; localStorage.setItem( MOCKSI_MODIFICATIONS, From 0fd8caedfee9812b7520b3a22ac0d8038b3c8e84 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 14:00:10 -0300 Subject: [PATCH 07/11] added some comments to explain logic --- apps/mocksi-lite/utils.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/mocksi-lite/utils.ts b/apps/mocksi-lite/utils.ts index d89c18e3..8f1405dd 100644 --- a/apps/mocksi-lite/utils.ts +++ b/apps/mocksi-lite/utils.ts @@ -55,6 +55,7 @@ export const loadModifications = () => { localStorage.getItem(MOCKSI_MODIFICATIONS) || "{}", ); for (const modification of Object.entries(modifications)) { + // value here is encoded, SHOULD NOT be a security risk to put it in the innerHTML const [querySelector, value] = modification; const hasIndex = querySelector.match(/\[+[0-9]\]/); if (hasIndex) { @@ -62,11 +63,11 @@ export const loadModifications = () => { const elemToModify = document.querySelectorAll( querySelector.replace(hasIndex[0], ""), )[index]; - //@ts-ignore EXTREMELY INSECURE!!!!!!!! + //@ts-ignore elemToModify.innerHTML = value; } else { const [elemToModify] = document.querySelectorAll(querySelector); - //@ts-ignore EXTREMELY INSECURE!!!!!!!! + //@ts-ignore elemToModify.innerHTML = value; } } From 29b4c3e45071d14de64c6f1a53f995b0339a108c Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 14:19:59 -0300 Subject: [PATCH 08/11] fixed loading modification on a different situation --- apps/mocksi-lite/utils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/mocksi-lite/utils.ts b/apps/mocksi-lite/utils.ts index 8f1405dd..87f88c06 100644 --- a/apps/mocksi-lite/utils.ts +++ b/apps/mocksi-lite/utils.ts @@ -57,7 +57,7 @@ export const loadModifications = () => { for (const modification of Object.entries(modifications)) { // value here is encoded, SHOULD NOT be a security risk to put it in the innerHTML const [querySelector, value] = modification; - const hasIndex = querySelector.match(/\[+[0-9]\]/); + const hasIndex = querySelector.match(/\[[0-9]+\]/); if (hasIndex) { const index: number = +hasIndex[0].replace("[", "").replace("]", ""); const elemToModify = document.querySelectorAll( @@ -71,5 +71,4 @@ export const loadModifications = () => { elemToModify.innerHTML = value; } } - console.log("loadedModifications!", modifications); }; From 79701ba60573d2b4f70fe2ca6b2cbaead12b4ccb Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 14:45:11 -0300 Subject: [PATCH 09/11] moved loadModificaations function to load changes --- apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx | 3 ++- apps/mocksi-lite/content/content.tsx | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx b/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx index a9b63cb6..fd5bb4a8 100644 --- a/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx +++ b/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx @@ -3,6 +3,7 @@ import TextField from "../../../common/TextField"; import editIcon from "../../../public/edit-icon.png"; import exportIcon from "../../../public/export-icon.png"; import { setEditorMode } from "../../content"; +import { loadModifications } from "../../../utils"; import type { Demo } from "./index"; const DemoItem = ({ name, customer }: Demo) => { @@ -16,7 +17,7 @@ const DemoItem = ({ name, customer }: Demo) => { - diff --git a/apps/mocksi-lite/content/content.tsx b/apps/mocksi-lite/content/content.tsx index 81a2d92b..55282987 100644 --- a/apps/mocksi-lite/content/content.tsx +++ b/apps/mocksi-lite/content/content.tsx @@ -182,7 +182,6 @@ document.addEventListener("DOMContentLoaded", initial); export const setEditorMode = (turnOn: boolean) => { if (turnOn) { - loadModifications(); document.body.addEventListener("dblclick", onDoubleClickText); } else { document.body.removeEventListener("dblclick", onDoubleClickText); From 649aeb2182ca08a1870382db4e365251e80a271d Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Tue, 4 Jun 2024 14:59:31 -0300 Subject: [PATCH 10/11] biome fixes --- apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx b/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx index fd5bb4a8..e3778542 100644 --- a/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx +++ b/apps/mocksi-lite/content/Popup/CreateDemo/DemoItem.tsx @@ -2,8 +2,8 @@ import Button, { Variant } from "../../../common/Button"; import TextField from "../../../common/TextField"; import editIcon from "../../../public/edit-icon.png"; import exportIcon from "../../../public/export-icon.png"; -import { setEditorMode } from "../../content"; import { loadModifications } from "../../../utils"; +import { setEditorMode } from "../../content"; import type { Demo } from "./index"; const DemoItem = ({ name, customer }: Demo) => { From 54f795f968f92571a8c8807c2213caa6400b45f7 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Wed, 5 Jun 2024 11:46:51 -0300 Subject: [PATCH 11/11] biome fixes --- apps/mocksi-lite/content/content.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mocksi-lite/content/content.tsx b/apps/mocksi-lite/content/content.tsx index 69846c2c..a8ad2640 100644 --- a/apps/mocksi-lite/content/content.tsx +++ b/apps/mocksi-lite/content/content.tsx @@ -1,6 +1,6 @@ import ReactDOM from "react-dom/client"; -import { saveModification } from "../utils"; import { MOCKSI_RECORDING_STATE, RecordingState } from "../consts"; +import { saveModification } from "../utils"; import ContentApp from "./ContentApp"; let root: ReactDOM.Root;