Regex Modal
code:script.js
// index.js
/*scrapbox.PageMenu.addMenu({
title: "Regex",
onClick: main,
});*/
function main() {
// 非表示になっているモーダルを表示
if (document.getElementById("regexModalContainer")) {
document.getElementById("regexModalContainer").style.display = "block";
setTimeout(() => document.getElementById("originalText").focus(), 100);
return;
}
const modalContainer = document.createElement("div");
modalContainer.id = "regexModalContainer";
// 元のテキストを入力するテキストエリア
const originalTextArea = document.createElement("textarea");
originalTextArea.id = "originalText";
originalTextArea.placeholder = "Original Text";
// 正規表現を入力するフィールド
const regexInput = document.createElement("input");
regexInput.id = "regexPattern";
regexInput.placeholder = "Regex Pattern";
// 置換テキストを入力するフィールド
const replaceInput = document.createElement("input");
replaceInput.id = "replaceText";
replaceInput.placeholder = "Replace Text";
// 置換結果を表示するエリア
const resultArea = document.createElement("div");
resultArea.id = "resultArea";
// エラーメッセージを表示するエリア
const errorArea = document.createElement("div");
errorArea.id = "errorArea";
// クリップボードにコピーするボタン
const copyButton = document.createElement("button");
copyButton.id = "copyButton";
copyButton.textContent = "Copy to Clipboard";
// モーダルを閉じるボタン
const closeButton = document.createElement("button");
closeButton.id = "closeButton";
closeButton.textContent = "Close";
// フィルターを追加するかどうかのチェックボックス
const setAsFilterCheckbox = document.createElement("input");
setAsFilterCheckbox.type = "checkbox";
setAsFilterCheckbox.id = "setAsFilter";
setAsFilterCheckbox.checked = true;
const setAsFilter = document.createElement("span");
const setAsFilterLabel = document.createElement("label");
setAsFilterLabel.textContent = "Set as Paste Filter";
setAsFilter.appendChild(setAsFilterCheckbox);
setAsFilter.appendChild(setAsFilterLabel);
// 各要素をモーダルに追加
modalContainer.appendChild(originalTextArea);
modalContainer.appendChild(regexInput);
modalContainer.appendChild(replaceInput);
modalContainer.appendChild(resultArea);
modalContainer.appendChild(errorArea);
modalContainer.appendChild(copyButton);
modalContainer.appendChild(closeButton);
modalContainer.appendChild(setAsFilter);
// モーダルをDOMに追加
document.body.appendChild(modalContainer);
// リアルタイムでの監視
document
.getElementById("originalText")
.addEventListener("input", performRegexReplace);
document
.getElementById("regexPattern")
.addEventListener("input", performRegexReplace);
document
.getElementById("replaceText")
.addEventListener("input", performRegexReplace);
// クリップボードにコピーするボタンにイベントリスナーを追加
document
.getElementById("copyButton")
.addEventListener("click", copyToClipboard);
// モーダルを閉じるボタンにイベントリスナーを追加
document
.getElementById("closeButton")
.addEventListener("click", () => {
modalContainer.style.display = "none";
if (document.getElementById("setAsFilter")?.checked) {
setFilter();
}
});
addStyle();
setTimeout(() => originalTextArea.focus(), 100);
}
let pattern = {regexPattern: null, replaceText: null};
function setFilter() {
if (document.getElementById("regexPattern").value + document.getElementById("replaceText").value === "") {
pattern.regexPattern = null
pattern.replaceText = null;
}
try {
const regexPattern = new RegExp(
document.getElementById("regexPattern").value,
"gvm"
);
const replaceText = replaceEscapeSequences(document.getElementById("replaceText").value);
pattern.regexPattern = regexPattern;
pattern.replaceText = replaceText;
} catch (error) {
// エラーが発生した場合、エラーメッセージを表示
document.getElementById("errorArea").innerText = Error: ${error.message};
}
}
function replaceEscapeSequences(str) {
(match, p1, p2, p3) => {
if(p1) {
switch(p1) {
case '0': return '\0';
case 'b': return '\b';
case 'f': return '\f';
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'v': return '\v';
default: return p1.length === 1 ? p1 : p1.slice(1);
}
}
if(p2) return String.fromCharCode(parseInt(p2, 8));
if(p3) return String.fromCodePoint(parseInt(p3, 16));
});
}
// リアルタイムでの監視は既に設定されているため、特に新たなコードは必要ありません。
// ただし、エラーハンドリングを追加します。
function performRegexReplace() {
document.getElementById("errorArea").innerText = "";
try {
const originalText = document.getElementById("originalText").value;
const regexPattern = new RegExp(
document.getElementById("regexPattern").value,
"gvm"
);
const replaceText = replaceEscapeSequences(document.getElementById("replaceText").value);
// 置換処理
const replacedText = originalText.replace(regexPattern, replaceText);
// 結果を表示
document.getElementById("resultArea").innerText = replacedText;
} catch (error) {
// エラーが発生した場合、エラーメッセージを表示
document.getElementById("errorArea").innerText = Error: ${error.message};
}
}
// クリップボードにコピーする関数
function copyToClipboard() {
const resultText = document.getElementById("resultArea").innerText;
navigator.clipboard
.writeText(resultText)
.then(() => {
document.getElementById("copyButton").textContent = "Copied";
setTimeout(() => {
document.getElementById("copyButton").textContent = "Copy to Clipboard";
}, 3000);
})
.catch((err) => {
alert("Error in copying text: " + err);
});
}
function addStyle() {
const css = `
/* モーダルの背景色と枠線 */
box-shadow: rgb(0 0 0 / 0.15) 0px 0px 14px 4px;
border-radius: 8px;
font-size: 14px;
padding: 20px;
width: min(500px, 90vw);
margin: auto;
position: fixed;
z-index: 999999;
top: 15vh;
max-height: 80vh;
overflow-y: scroll;
left: 50%;
transform: translateX(-50%);
}
/* テキストエリアのスタイリング */
width: 100%;
padding: 10px;
margin: 10px 0;
border-radius: 4px;
resize: vertical;
min-height: 30px;
}
/* 正規表現と置換テキストの入力フィールドのスタイリング */
width: 100%;
padding: 8px;
margin: 10px 0;
border-radius: 4px;
}
/* ボタンのデザイン */
padding: 12px 20px;
border-radius: 4px;
cursor: pointer;
}
/* コピーするボタンのスタイリング */
color: white;
border: none;
margin-right: 10px;
}
/* 閉じるボタンのスタイリング */
background-color: transparent;
}
/* ホバーエフェクト */
}
/* 編集結果を表示するresultAreaのスタイリング */
border-radius: 4px;
padding: 10px;
margin: 10px 0;
line-height: 1.33;
white-space: pre-wrap;
}
/* エラーメッセージを表示するerrorAreaのスタイリング */
color: red;
font-weight: bold;
}
`;
// スタイルをDOMに追加
const style = document.createElement("style");
style.textContent = css;
document.head.appendChild(style);
}
export {pattern, main}