From ec9f0689d0ec0d5ed492b5a1ea8b29b2bce9d53a Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Fri, 7 Jun 2024 15:55:40 +0200
Subject: [PATCH 01/25] added draggable ui element
---
mikupad.html | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 239 insertions(+), 2 deletions(-)
diff --git a/mikupad.html b/mikupad.html
index bdc7661..a63069b 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -344,6 +344,54 @@
font-size: 0.8rem;
}
+.widget-title {
+ -webkit-user-select: none; /* Safari */
+ -ms-user-select: none; /* IE 10 and IE 11 */
+ user-select: none; /* Standard syntax */
+ padding:0.2em;
+ font-weight: bold;
+ font-size: 110%;
+ background-color: var(--color-base-40);
+ border-radius:2px;
+ width: calc(100% - 2em);
+}
+
+#searchAndReplace {
+ position: absolute;
+ width: 70%;
+ background: var(--color-base-50);
+ top:.75em;
+ left:.75em;
+ border-radius:3px;
+ padding:0.25em;
+}
+
+#searchAndReplace .widget-container {
+ position: relative;
+}
+#searchAndReplace .button-widget-top {
+ position: absolute;
+ top:0.1em;
+ right:0.1em;
+}
+
+.searchAndReplace-inputs {
+ display: flex;
+ flex-direction: row;
+ gap: 8px;
+ padding: .2em;
+}
+.searchAndReplace-inputs .InputBox {
+ width: 100%;
+}
+.searchAndReplace-inputs .SelectBox {
+ width: 40%;
+}
+
+/* .widget-body {
+
+} */
+
.modal-overlay {
position: fixed;
top: 0;
@@ -1975,8 +2023,6 @@
`;
}
-
-
function Modal({ isOpen, onClose, title, description, children, ...props }) {
if (!isOpen) {
return null;
@@ -2014,6 +2060,168 @@
`;
}
+//https://stackoverflow.com/questions/20926551/recommended-way-of-making-react-component-div-draggable
+function Draggable({ isOpen, onClose, title, id, children, ...props }) {
+ function getDefaultProps() {
+ return {
+ // allow the initial position to be passed in as a prop
+ initialPos: {x: 0, y: 0}
+ }
+ }
+ function getInitialState() {
+ return {
+ pos: this.props.initialPos,
+ dragging: false,
+ rel: null // position relative to the cursor
+ }
+ }
+ // we could get away with not having this (and just having the listeners on
+ // our div), but then the experience would be possibly be janky. If there's
+ // anything w/ a higher z-index that gets in the way, then you're toast,
+ // etc.
+ function componentDidUpdate(props, state) {
+ if (this.state.dragging && !state.dragging) {
+ document.addEventListener('mousemove', this.onMouseMove)
+ document.addEventListener('mouseup', this.onMouseUp)
+ } else if (!this.state.dragging && state.dragging) {
+ document.removeEventListener('mousemove', this.onMouseMove)
+ document.removeEventListener('mouseup', this.onMouseUp)
+ }
+ }
+
+ // calculate relative position of the mouse and set dragging=true
+ function onMouseDown(e) {
+ // only left mouse button
+ if (e.button !== 0) return
+ var pos = $(this.getDOMNode()).offset()
+ this.setState({
+ dragging: true,
+ rel: {
+ x: e.pageX - pos.left,
+ y: e.pageY - pos.top
+ }
+ })
+ e.stopPropagation()
+ e.preventDefault()
+ }
+ function onMouseUp(e) {
+ this.setState({dragging: false})
+ e.stopPropagation()
+ e.preventDefault()
+ }
+ function onMouseMove(e) {
+ if (!this.state.dragging) return
+ this.setState({
+ pos: {
+ x: e.pageX - this.state.rel.x,
+ y: e.pageY - this.state.rel.y
+ }
+ })
+ e.stopPropagation()
+ e.preventDefault()
+ }
+ function render() {
+ // transferPropsTo will merge style & other props passed into our
+ // component to also be on the child DIV.
+ return this.transferPropsTo(React.DOM.div({
+ onMouseDown: this.onMouseDown,
+ style: {
+ left: this.state.pos.x + 'px',
+ top: this.state.pos.y + 'px'
+ }
+ }, this.props.children))
+ }
+}
+
+
+function Widget({ isOpen, onClose, title, id, children, ...props }) {
+ if (!isOpen) {
+ return null;
+ }
+
+ const [position, setPosition] = useState({ x: 0, y: 0 });
+ const [isDragging, setIsDragging] = useState(false);
+ const dragRef = useRef(null);
+
+ useEffect(() => {
+ const handleMouseMove = (e) => {
+ if (!isDragging) return;
+ const deltaX = e.clientX - dragRef.current.startX;
+ const deltaY = e.clientY - dragRef.current.startY;
+ setPosition({
+ x: dragRef.current.initialX + deltaX,
+ y: dragRef.current.initialY + deltaY,
+ });
+ };
+
+ const handleMouseUp = () => {
+ setIsDragging(false);
+ };
+
+ document.addEventListener('mousemove', handleMouseMove);
+ document.addEventListener('mouseup', handleMouseUp);
+
+ return () => {
+ document.removeEventListener('mousemove', handleMouseMove);
+ document.removeEventListener('mouseup', handleMouseUp);
+ };
+ }, [isDragging]);
+
+ const handleMouseDown = (e) => {
+ setIsDragging(true);
+ dragRef.current = {
+ startX: e.clientX,
+ startY: e.clientY,
+ initialX: position.x,
+ initialY: position.y,
+ };
+ };
+
+ useEffect(() => {
+ const onKeyDown = (event) => {
+ if (event.key === 'Escape') {
+ onClose();
+ }
+ };
+ document.addEventListener('keydown', onKeyDown);
+ return () => {
+ document.removeEventListener('keydown', onKeyDown);
+ };
+ }, []);
+
+ return html`
+
`;
+}
+function SearchAndReplaceWidget({ isOpen, closeWidget, id, children, ...props }) {
+ return html`
+ <${Widget} isOpen=${isOpen} onClose=${closeWidget}
+ title="Search and Replace"
+ id="${id}">
+ ${children}
+ ${Widget}>`;
+}
+
function EditorPreferencesModal({ isOpen, closeModal, children }) {
return html`
<${Modal} isOpen=${isOpen} onClose=${closeModal}
@@ -3747,6 +3955,9 @@
const [authorNoteTokens, setAuthorNoteTokens] = useSessionState('authorNoteTokens', defaultPresets.authorNoteTokens);
const [authorNoteDepth, setAuthorNoteDepth] = useSessionState('authorNoteDepth', defaultPresets.authorNoteDepth);
const [worldInfo, setWorldInfo] = useSessionState('worldInfo', defaultPresets.worldInfo);
+ const [searchAndReplaceMode, setSearchAndReplaceMode] = usePersistentState('searchAndReplaceMode', 0);
+ const [searchTerm, setSearchTerm] = usePersistentState('searchTerm', '');
+ const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm', '');
function replacePlaceholders(string,placeholders) {
@@ -4952,6 +5163,29 @@
`;
})}` : null}
+ <${SearchAndReplaceWidget}
+ isOpen=${modalState.searchAndReplace}
+ closeWidget=${() => closeModal("searchAndReplace")}
+ id="searchAndReplace"
+ >
+
+ <${SelectBox}
+ label="Mode"
+ value=${searchAndReplaceMode}
+ onValueChange=${setSearchAndReplaceMode}
+ options=${[
+ { name: 'Plaintext', value: 0 },
+ { name: 'Regex', value: 1 },
+ { name: 'Template', value: 2 },
+ ]}/>
+ ${searchAndReplaceMode == 0 && html`
+ <${InputBox} label="Search This" type="text"
+ readOnly=${!!cancel} value=${searchTerm} onValueChange=${setSearchTerm}/>
+ <${InputBox} label="Replace With" type="text"
+ readOnly=${!!cancel} value=${replaceTerm} onValueChange=${setReplaceTerm}/>
+ `}
+
+ ${SearchAndReplaceWidget}>
${probs ? html`
+
${!!lastError && html`
${lastError}`}
From 0c50b1e6a5910ac5908608f092b971ae3dd22b8c Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Fri, 7 Jun 2024 16:55:37 +0200
Subject: [PATCH 02/25] widget component functional, plaintext replace
functional
---
mikupad.html | 115 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 85 insertions(+), 30 deletions(-)
diff --git a/mikupad.html b/mikupad.html
index a63069b..b9cbc01 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -344,6 +344,10 @@
font-size: 0.8rem;
}
+.widget-body {
+ z-index: 99;
+}
+
.widget-title {
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
@@ -369,17 +373,25 @@
#searchAndReplace .widget-container {
position: relative;
}
-#searchAndReplace .button-widget-top {
+
+.button-widget-top {
+ all:unset;
position: absolute;
- top:0.1em;
- right:0.1em;
+ top: 0.25em;
+ right: 0.15em;
+ width:1.25em;
+ height:1.25em;
+ border-radius: 3px;
+}
+#searchAndReplace .widget-content {
+ padding: .2em;
}
.searchAndReplace-inputs {
display: flex;
flex-direction: row;
gap: 8px;
- padding: .2em;
+ margin-bottom:8px;
}
.searchAndReplace-inputs .InputBox {
width: 100%;
@@ -388,9 +400,6 @@
width: 40%;
}
-/* .widget-body {
-
-} */
.modal-overlay {
position: fixed;
@@ -2213,12 +2222,77 @@
`;
}
-function SearchAndReplaceWidget({ isOpen, closeWidget, id, children, ...props }) {
+function SearchAndReplaceWidget({ isOpen, closeWidget, id, children, promptArea, cancel, ...props }) {
+ const [searchAndReplaceMode, setSearchAndReplaceMode] = usePersistentState('searchAndReplaceMode', 0);
+ const [searchTerm, setSearchTerm] = usePersistentState('searchTerm', '');
+ const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm', '');
+ const [inputElement, setInputElement] = useState(null);
+
+ useEffect(() => {
+ if (promptArea.current) {
+ setInputElement(promptArea.current);
+ }
+ }, [promptArea]);
+
+
+ console.log(promptArea)
+ console.log(promptArea.current)
+
+
+ function handleSearchAndReplace(mode,search,replace) {
+ // console.log(prompt)
+ if (!search)
+ return
+
+ switch(mode) {
+ case 0:
+ plaintextReplace(search,replace,inputElement)
+ break;
+ case 1:
+ regexReplace(search,replace,inputElement)
+ break;
+ case 2:
+ templateReplace(search,replace,inputElement)
+ break;
+ }
+ }
+
+ function plaintextReplace(search,replace,elem) {
+ // console.log(elem.value)
+ // need to figure out a smart way to keep the cursor position
+ elem.value = elem.value.replaceAll(search,replace)
+ }
+
return html`
<${Widget} isOpen=${isOpen} onClose=${closeWidget}
title="Search and Replace"
id="${id}">
${children}
+
+ <${SelectBox}
+ label="Mode"
+ value=${searchAndReplaceMode}
+ onValueChange=${setSearchAndReplaceMode}
+ options=${[
+ { name: 'Plaintext', value: 0 },
+ { name: 'Regex', value: 1 },
+ { name: 'Template', value: 2 },
+ ]}/>
+ ${searchAndReplaceMode == 0 && html`
+ <${InputBox} label="Search This" type="text"
+ placeholder="Hatusne Miku"
+ readOnly=${!!cancel} value=${searchTerm} onValueChange=${setSearchTerm}/>
+ <${InputBox} label="Replace With" type="text"
+ placeholder="Makise Kurisu"
+ readOnly=${!!cancel} value=${replaceTerm} onValueChange=${setReplaceTerm}/>
+ `}
+
+
${Widget}>`;
}
@@ -3955,9 +4029,7 @@
const [authorNoteTokens, setAuthorNoteTokens] = useSessionState('authorNoteTokens', defaultPresets.authorNoteTokens);
const [authorNoteDepth, setAuthorNoteDepth] = useSessionState('authorNoteDepth', defaultPresets.authorNoteDepth);
const [worldInfo, setWorldInfo] = useSessionState('worldInfo', defaultPresets.worldInfo);
- const [searchAndReplaceMode, setSearchAndReplaceMode] = usePersistentState('searchAndReplaceMode', 0);
- const [searchTerm, setSearchTerm] = usePersistentState('searchTerm', '');
- const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm', '');
+
function replacePlaceholders(string,placeholders) {
@@ -5167,25 +5239,8 @@
isOpen=${modalState.searchAndReplace}
closeWidget=${() => closeModal("searchAndReplace")}
id="searchAndReplace"
- >
-
- <${SelectBox}
- label="Mode"
- value=${searchAndReplaceMode}
- onValueChange=${setSearchAndReplaceMode}
- options=${[
- { name: 'Plaintext', value: 0 },
- { name: 'Regex', value: 1 },
- { name: 'Template', value: 2 },
- ]}/>
- ${searchAndReplaceMode == 0 && html`
- <${InputBox} label="Search This" type="text"
- readOnly=${!!cancel} value=${searchTerm} onValueChange=${setSearchTerm}/>
- <${InputBox} label="Replace With" type="text"
- readOnly=${!!cancel} value=${replaceTerm} onValueChange=${setReplaceTerm}/>
- `}
-
- ${SearchAndReplaceWidget}>
+ promptArea=${promptArea}
+ cancel=${cancel}/>
${probs ? html`
Date: Fri, 7 Jun 2024 17:04:53 +0200
Subject: [PATCH 03/25] fixed serif light theme
---
mikupad.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/mikupad.html b/mikupad.html
index b9cbc01..6d45186 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -346,6 +346,7 @@
.widget-body {
z-index: 99;
+ color: var(--color-light)
}
.widget-title {
From 2c431447393a06c041a557b794db33b426629934 Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Fri, 7 Jun 2024 17:17:35 +0200
Subject: [PATCH 04/25] added error display
---
mikupad.html | 86 +++++-----------------------------------------------
1 file changed, 7 insertions(+), 79 deletions(-)
diff --git a/mikupad.html b/mikupad.html
index 6d45186..b76908a 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -2070,80 +2070,6 @@
`;
}
-//https://stackoverflow.com/questions/20926551/recommended-way-of-making-react-component-div-draggable
-function Draggable({ isOpen, onClose, title, id, children, ...props }) {
- function getDefaultProps() {
- return {
- // allow the initial position to be passed in as a prop
- initialPos: {x: 0, y: 0}
- }
- }
- function getInitialState() {
- return {
- pos: this.props.initialPos,
- dragging: false,
- rel: null // position relative to the cursor
- }
- }
- // we could get away with not having this (and just having the listeners on
- // our div), but then the experience would be possibly be janky. If there's
- // anything w/ a higher z-index that gets in the way, then you're toast,
- // etc.
- function componentDidUpdate(props, state) {
- if (this.state.dragging && !state.dragging) {
- document.addEventListener('mousemove', this.onMouseMove)
- document.addEventListener('mouseup', this.onMouseUp)
- } else if (!this.state.dragging && state.dragging) {
- document.removeEventListener('mousemove', this.onMouseMove)
- document.removeEventListener('mouseup', this.onMouseUp)
- }
- }
-
- // calculate relative position of the mouse and set dragging=true
- function onMouseDown(e) {
- // only left mouse button
- if (e.button !== 0) return
- var pos = $(this.getDOMNode()).offset()
- this.setState({
- dragging: true,
- rel: {
- x: e.pageX - pos.left,
- y: e.pageY - pos.top
- }
- })
- e.stopPropagation()
- e.preventDefault()
- }
- function onMouseUp(e) {
- this.setState({dragging: false})
- e.stopPropagation()
- e.preventDefault()
- }
- function onMouseMove(e) {
- if (!this.state.dragging) return
- this.setState({
- pos: {
- x: e.pageX - this.state.rel.x,
- y: e.pageY - this.state.rel.y
- }
- })
- e.stopPropagation()
- e.preventDefault()
- }
- function render() {
- // transferPropsTo will merge style & other props passed into our
- // component to also be on the child DIV.
- return this.transferPropsTo(React.DOM.div({
- onMouseDown: this.onMouseDown,
- style: {
- left: this.state.pos.x + 'px',
- top: this.state.pos.y + 'px'
- }
- }, this.props.children))
- }
-}
-
-
function Widget({ isOpen, onClose, title, id, children, ...props }) {
if (!isOpen) {
return null;
@@ -2224,6 +2150,7 @@
`;
}
function SearchAndReplaceWidget({ isOpen, closeWidget, id, children, promptArea, cancel, ...props }) {
+ const [searchAndReplaceError, setSearchAndReplaceError] = useState(undefined);
const [searchAndReplaceMode, setSearchAndReplaceMode] = usePersistentState('searchAndReplaceMode', 0);
const [searchTerm, setSearchTerm] = usePersistentState('searchTerm', '');
const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm', '');
@@ -2235,12 +2162,8 @@
}
}, [promptArea]);
-
- console.log(promptArea)
- console.log(promptArea.current)
-
-
function handleSearchAndReplace(mode,search,replace) {
+ setSearchAndReplaceError(undefined)
// console.log(prompt)
if (!search)
return
@@ -2262,6 +2185,9 @@
// console.log(elem.value)
// need to figure out a smart way to keep the cursor position
elem.value = elem.value.replaceAll(search,replace)
+ // TODO
+ // THIS DOESN'T SAVE REPLACEMENTS IF YOU DO NOT ADD ANY MANUAL EDITS
+ // BEFORE PREDICTING OR RELOADING
}
return html`
@@ -2294,6 +2220,8 @@
onClick=${() => handleSearchAndReplace(searchAndReplaceMode,searchTerm,replaceTerm)}>
Replace
+ ${!!searchAndReplaceError && html`
+ ${searchAndReplaceError}
`}
${Widget}>`;
}
From bc5a4eecf11ed09c86cdd564212b5e31fbdc5d0d Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Fri, 7 Jun 2024 18:38:57 +0200
Subject: [PATCH 05/25] regex replace functional
---
mikupad.html | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/mikupad.html b/mikupad.html
index b76908a..f19fdbd 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -2152,8 +2152,8 @@
function SearchAndReplaceWidget({ isOpen, closeWidget, id, children, promptArea, cancel, ...props }) {
const [searchAndReplaceError, setSearchAndReplaceError] = useState(undefined);
const [searchAndReplaceMode, setSearchAndReplaceMode] = usePersistentState('searchAndReplaceMode', 0);
- const [searchTerm, setSearchTerm] = usePersistentState('searchTerm', '');
- const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm', '');
+ const [searchTerm, setSearchTerm] = usePersistentState('searchTerm','');
+ const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm','');
const [inputElement, setInputElement] = useState(null);
useEffect(() => {
@@ -2188,6 +2188,18 @@
// TODO
// THIS DOESN'T SAVE REPLACEMENTS IF YOU DO NOT ADD ANY MANUAL EDITS
// BEFORE PREDICTING OR RELOADING
+ // TODO
+ // Add this to undo/redo
+ }
+ function regexReplace(search,replace,elem) {
+ let regexComponents = search.match(/\/([^\/]+)\/(\w+)?/)
+ try {
+ let re = new RegExp(String.raw`${regexComponents[1]}`, `${regexComponents[2] ?? ""}`);
+ elem.value = elem.value.replace(re,replace)
+ }
+ catch {
+ setSearchAndReplaceError("Error: Not a RegEx. Is it wrapped in '/'?")
+ }
}
return html`
@@ -2203,7 +2215,7 @@
options=${[
{ name: 'Plaintext', value: 0 },
{ name: 'Regex', value: 1 },
- { name: 'Template', value: 2 },
+ // { name: 'Template', value: 2 },
]}/>
${searchAndReplaceMode == 0 && html`
<${InputBox} label="Search This" type="text"
@@ -2213,6 +2225,14 @@
placeholder="Makise Kurisu"
readOnly=${!!cancel} value=${replaceTerm} onValueChange=${setReplaceTerm}/>
`}
+ ${searchAndReplaceMode == 1 && html`
+ <${InputBox} label="Search This" type="text"
+ placeholder="/(\\w+) Miku/gi"
+ readOnly=${!!cancel} value=${searchTerm} onValueChange=${setSearchTerm}/>
+ <${InputBox} label="Replace With" type="text"
+ placeholder="$1 Kurisu"
+ readOnly=${!!cancel} value=${replaceTerm} onValueChange=${setReplaceTerm}/>
+ `}
handleFindNext(searchAndReplaceMode,searchTerm)}>
+ onClick=${() => handleFindNext(searchAndReplaceMode,searchTerm,searchFlags)}>
Find Next
handleSearchAndReplace(searchAndReplaceMode,searchTerm,replaceTerm)}>
+ onClick=${() => handleSearchAndReplace(searchAndReplaceMode,searchTerm,searchFlags,replaceTerm)}>
Replace All
From d3067ff03ea3ca3925ca1fea52d430d02755471a Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Sat, 8 Jun 2024 12:43:23 +0200
Subject: [PATCH 18/25] fixed issue with empty flag field
---
mikupad.html | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/mikupad.html b/mikupad.html
index c6d554d..a15fb9a 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -3263,6 +3263,8 @@
try {
if (flags && !flags.includes("g"))
flags += "g" // if no global flag, while loop is infinite
+ else if (flags == "")
+ flags = "g"
let re = new RegExp(String.raw`${search}`, String.raw`${flags ?? "g"}`);
while ((match = re.exec(text)) !== null) {
positions.push({ start: match.index, end: re.lastIndex });
@@ -3274,10 +3276,7 @@
catch (e) {
reportError(e);
const errStr = e.toString()
- if (errStr == "TypeError: regexComponents is null")
- setSearchAndReplaceError("Error: Regex not wrapped in '/'")
- else
- setSearchAndReplaceError(errStr)
+ setSearchAndReplaceError(errStr)
}
}
return positions;
@@ -3351,10 +3350,7 @@
catch (e) {
reportError(e);
const errStr = e.toString()
- if (errStr == "TypeError: regexComponents is null")
- setSearchAndReplaceError("Error: Regex not wrapped in '/'")
- else
- setSearchAndReplaceError(errStr)
+ setSearchAndReplaceError(errStr)
}
}
From 9232a789e0cf60a431505efaad9efc16ecf55943 Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Sat, 8 Jun 2024 17:57:55 +0200
Subject: [PATCH 19/25] box-shadow for widgets
---
mikupad.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mikupad.html b/mikupad.html
index a15fb9a..406949e 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -354,7 +354,8 @@
.widget-body {
z-index: 10;
- color: var(--color-light)
+ color: var(--color-light);
+ box-shadow: #0004 2px 2px 6px 2px;
}
html.nockoffAI #searchAndReplace {
background: var(--color-sidebar);
From b51a490bb2910a21a1e7536377b4d665fde4cac9 Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Sat, 8 Jun 2024 23:06:08 +0200
Subject: [PATCH 20/25] show warning when no matches found
---
mikupad.html | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/mikupad.html b/mikupad.html
index 406949e..267f718 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -3278,6 +3278,7 @@
reportError(e);
const errStr = e.toString()
setSearchAndReplaceError(errStr)
+ return false
}
}
return positions;
@@ -3312,6 +3313,8 @@
function findAndStorePositions(mode,search,flags,elem) {
positions = findAllMatches(mode, search, flags, elem);
currentIndex = -1;
+ if (positions.length === 0)
+ setSearchAndReplaceError(`Warning: No matches found for ${ (mode==0?"Plaintext":mode==1?"RegEx":"Template") } \'${search}\'`)
}
@@ -3322,6 +3325,13 @@
setSearchAndReplaceError(undefined)
if (!search)
return
+ positions = findAllMatches(mode, search, flags, inputElement);
+ console.log(positions)
+ if (positions.length === 0) {
+ setSearchAndReplaceError(`Warning: No matches found for ${ (mode==0?"Plaintext":mode==1?"RegEx":"Template") } \'${search}\'`)
+ return
+ }
+
switch(mode) {
case 0:
plaintextReplace(search,replace,inputElement)
From 67a086891860a39d469cc7fb39359b3d32a83e8c Mon Sep 17 00:00:00 2001
From: neCo <50079394+neCo2@users.noreply.github.com>
Date: Sun, 9 Jun 2024 12:07:51 +0200
Subject: [PATCH 21/25] added count button
---
mikupad.html | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/mikupad.html b/mikupad.html
index 267f718..0e1aac5 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -443,6 +443,9 @@
#searchAndReplace .findButton svg {
width: .75em;
}
+.number-matches {
+ align-content: center;
+}
.modal-overlay {
@@ -3201,6 +3204,7 @@
const [searchTerm, setSearchTerm] = usePersistentState('searchTerm','');
const [searchFlags, setSearchFlags] = usePersistentState('searchFlags','gi');
const [replaceTerm, setReplaceTerm] = usePersistentState('replaceTerm','');
+ const [numMatches, setNumMatches] = useState(0);
const [inputElement, setInputElement] = useState(null);
useEffect(() => {
@@ -3242,7 +3246,6 @@
}
}
- // Plaintext Find
let positions = [];
let currentIndex = -1;
@@ -3278,7 +3281,7 @@
reportError(e);
const errStr = e.toString()
setSearchAndReplaceError(errStr)
- return false
+ return null
}
}
return positions;
@@ -3317,8 +3320,6 @@
setSearchAndReplaceError(`Warning: No matches found for ${ (mode==0?"Plaintext":mode==1?"RegEx":"Template") } \'${search}\'`)
}
-
-
function handleSearchAndReplace(mode,search,flags,replace) {
// TODO
// Add this to undo/redo
@@ -3326,7 +3327,6 @@
if (!search)
return
positions = findAllMatches(mode, search, flags, inputElement);
- console.log(positions)
if (positions.length === 0) {
setSearchAndReplaceError(`Warning: No matches found for ${ (mode==0?"Plaintext":mode==1?"RegEx":"Template") } \'${search}\'`)
return
@@ -3365,6 +3365,20 @@
}
}
+ function countMatches(mode, search, flags) {
+ setSearchAndReplaceError(undefined)
+ if (!searchTerm)
+ return
+ positions = findAllMatches(mode, search, flags, inputElement);
+ setNumMatches(positions.length ?? 0)
+ if (positions.length === 0)
+ setSearchAndReplaceError(`Warning: No matches found for ${ (mode==0?"Plaintext":mode==1?"RegEx":"Template") } \'${search}\'`)
+ }
+
+ useEffect(() => {
+ setNumMatches(0)
+ }, [searchTerm,searchFlags]);
+
return html`
<${Widget} isOpen=${isOpen} onClose=${closeWidget}
title="Search and Replace"
@@ -3404,6 +3418,15 @@
-
+ <${SVG_Close}/>
@@ -3605,14 +3625,14 @@
title="Find Previous Match"
disabled=${!!cancel}
onClick=${() => handleFindPrev(searchAndReplaceMode,searchTerm,searchFlags)}>
-
+ <${SVG_ArrowUp}/>
handleFindNext(searchAndReplaceMode,searchTerm,searchFlags)}>
-
+ <${SVG_ArrowDown}/>
Find Next
toggleModal("prompt")}>
<${SVG_Settings}/>
+
toggleModal("searchAndReplace")}>
+ <${SVG_SearchAndReplace} style=${{"height":"1.3em"}} />
+
From 9daff6ab2254f2e7c93e0fc2918019e58574f3f2 Mon Sep 17 00:00:00 2001
From: neCo2 <50079394+neCo2@users.noreply.github.com>
Date: Mon, 17 Jun 2024 23:28:15 +0200
Subject: [PATCH 25/25] fix findnext button layout
---
mikupad.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mikupad.html b/mikupad.html
index e291d3e..f56eda0 100644
--- a/mikupad.html
+++ b/mikupad.html
@@ -3631,7 +3631,7 @@
<${SVG_ArrowUp}/>
handleFindNext(searchAndReplaceMode,searchTerm,searchFlags)}>