Skip to content

Commit 1bfe8d8

Browse files
committed
project-init
0 parents  commit 1bfe8d8

File tree

7 files changed

+839
-0
lines changed

7 files changed

+839
-0
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"liveServer.settings.port": 5501
3+
}

formatter.html

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<meta name="description" content="Format and beautify your JSON data online. Copy, download, and validate your JSON instantly. 100% free and secure.">
7+
<meta name="theme-color" content="#ffffff">
8+
<!-- OpenGraph -->
9+
<meta property="og:title" content="JSON Formatter Online — Free, Fast, and Secure">
10+
<meta property="og:description" content="Format and beautify your JSON data online. Copy, download, and validate your JSON instantly. 100% free and secure.">
11+
<meta property="og:type" content="website">
12+
<meta property="og:url" content="YOUR_DEPLOYMENT_URL_HERE/formatter.html"> <!-- Replace with actual URL later -->
13+
<!-- <meta property="og:image" content="YOUR_OG_IMAGE_URL_HERE"> --> <!-- Add OG image later -->
14+
<!-- Twitter Card -->
15+
<meta name="twitter:card" content="summary_large_image">
16+
<meta name="twitter:title" content="JSON Formatter Online — Free, Fast, and Secure">
17+
<meta name="twitter:description" content="Format and beautify your JSON data online. Copy, download, and validate your JSON instantly. 100% free and secure.">
18+
<!-- <meta name="twitter:image" content="YOUR_TWITTER_IMAGE_URL_HERE"> --> <!-- Add Twitter image later -->
19+
20+
<title>JSON Formatter Online — Free, Fast, and Secure</title>
21+
<script>
22+
// Configure Tailwind to use the 'class' strategy for dark mode
23+
tailwind.config = {
24+
darkMode: 'class',
25+
}
26+
</script>
27+
<script src="https://cdn.tailwindcss.com"></script>
28+
29+
<script>
30+
31+
tailwind.config = {
32+
darkMode: 'class', }
33+
</script>
34+
35+
<link rel="stylesheet" href="style.css">
36+
<!-- Add favicon link later -->
37+
<!-- <link rel="icon" href="favicon.ico" type="image/x-icon"> -->
38+
39+
<!-- Schema Markup -->
40+
<script type="application/ld+json">
41+
{
42+
"@context": "https://schema.org",
43+
"@type": "WebPage",
44+
"name": "JSON Formatter Online",
45+
"description": "Format and beautify your JSON data online. Copy, download, and validate your JSON instantly. 100% free and secure.",
46+
"url": "YOUR_DEPLOYMENT_URL_HERE/formatter.html", // Replace with actual URL later
47+
"mainEntity": {
48+
"@type": "SoftwareApplication",
49+
"name": "JSON Formatter Tool",
50+
"applicationCategory": "DeveloperTool",
51+
"operatingSystem": "All",
52+
"offers": {
53+
"@type": "Offer",
54+
"price": "0",
55+
"priceCurrency": "USD"
56+
}
57+
}
58+
}
59+
</script>
60+
<script type="application/ld+json">
61+
{
62+
"@context": "https://schema.org",
63+
"@type": "FAQPage",
64+
"mainEntity": [
65+
{
66+
"@type": "Question",
67+
"name": "How to format JSON online?",
68+
"acceptedAnswer": {
69+
"@type": "Answer",
70+
"text": "Simply paste your raw JSON data into the input area. The tool will automatically validate and format it into a readable structure. You can then copy the formatted JSON or download it as a file."
71+
}
72+
},
73+
{
74+
"@type": "Question",
75+
"name": "Is my JSON data secure?",
76+
"acceptedAnswer": {
77+
"@type": "Answer",
78+
"text": "Yes, absolutely. All JSON processing is done entirely within your browser using JavaScript. Your data is never sent to our servers, ensuring complete privacy and security."
79+
}
80+
},
81+
{
82+
"@type": "Question",
83+
"name": "Can I download the formatted JSON?",
84+
"acceptedAnswer": {
85+
"@type": "Answer",
86+
"text": "Yes, after formatting your JSON, you can click the 'Download JSON' button to save the formatted data as a .json file directly to your computer."
87+
}
88+
}
89+
]
90+
}
91+
</script>
92+
</head>
93+
<body class="bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100 font-sans">
94+
<nav class="bg-white dark:bg-gray-800 shadow p-4 flex justify-between items-center">
95+
<div class="text-xl font-bold">JSON Tools</div>
96+
<div>
97+
<a href="/" class="px-3 py-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700">JSON Diff</a>
98+
<a href="/formatter.html" class="px-3 py-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700">JSON Formatter</a>
99+
<button id="darkModeToggle" class="ml-4 px-3 py-2 rounded focus:outline-none dark:text-gray-200">🌙/☀️</button>
100+
</div>
101+
</nav>
102+
103+
<main class="container mx-auto p-4 mt-8">
104+
<section id="intro" class="text-center mb-12">
105+
<h1 class="text-4xl font-bold mb-4">Free Online JSON Formatter</h1>
106+
<p class="text-lg mb-6">Format and beautify your JSON data online. Copy, download, and validate your JSON instantly. 100% free and secure.</p>
107+
<div class="space-x-4">
108+
<a href="/" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded transition duration-300">
109+
Go to JSON Diff Tool
110+
</a>
111+
</div>
112+
</section>
113+
114+
<section id="formatter-tool">
115+
<div class="mb-4">
116+
<label for="jsonInput" class="block text-sm font-medium mb-1">Paste your JSON here:</label>
117+
<textarea id="jsonInput" rows="15" class="w-full p-2 border rounded shadow-sm dark:bg-gray-700 dark:border-gray-600 focus:ring-blue-500 focus:border-blue-500" placeholder="Paste or type your JSON data here..."></textarea>
118+
<div id="validationError" class="text-red-500 dark:text-red-400 mt-1 text-sm hidden">Invalid JSON</div>
119+
</div>
120+
121+
<div class="flex flex-wrap items-center gap-4 mb-4">
122+
<button id="formatBtn" class="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded transition duration-300">
123+
Format JSON
124+
</button>
125+
<button id="minifyBtn" class="bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-2 px-4 rounded transition duration-300">
126+
Minify JSON
127+
</button>
128+
<button id="copyBtn" class="bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded transition duration-300">
129+
Copy to Clipboard
130+
</button>
131+
<button id="downloadBtn" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded transition duration-300">
132+
Download JSON
133+
</button>
134+
<label class="flex items-center space-x-2 cursor-pointer">
135+
<input type="checkbox" id="autoFormat" class="form-checkbox h-5 w-5 text-blue-600 dark:bg-gray-700 dark:border-gray-600 rounded">
136+
<span class="text-sm">Auto-format on paste</span>
137+
</label>
138+
</div>
139+
140+
<div>
141+
<h2 class="text-2xl font-semibold mb-2">Formatted Output:</h2>
142+
<pre id="jsonOutput" class="p-4 border rounded bg-white dark:bg-gray-800 shadow-sm min-h-[200px] overflow-auto whitespace-pre-wrap break-words"><code class="language-json"></code></pre>
143+
<p id="outputPlaceholder" class="text-gray-500 dark:text-gray-400">Formatted JSON will appear here.</p>
144+
</div>
145+
</section>
146+
147+
<section id="faq" class="mt-12">
148+
<h2 class="text-3xl font-bold text-center mb-6">Frequently Asked Questions (FAQ)</h2>
149+
<div class="space-y-4 max-w-2xl mx-auto">
150+
<details class="bg-white dark:bg-gray-800 p-4 rounded shadow">
151+
<summary class="font-semibold cursor-pointer">How to format JSON online?</summary>
152+
<p class="mt-2 text-gray-700 dark:text-gray-300">Simply paste your raw JSON data into the input area. The tool will automatically validate and format it into a readable structure. You can then copy the formatted JSON or download it as a file.</p>
153+
</details>
154+
<details class="bg-white dark:bg-gray-800 p-4 rounded shadow">
155+
<summary class="font-semibold cursor-pointer">Is my JSON data secure?</summary>
156+
<p class="mt-2 text-gray-700 dark:text-gray-300">Yes, absolutely. All JSON processing is done entirely within your browser using JavaScript. Your data is never sent to our servers, ensuring complete privacy and security.</p>
157+
</details>
158+
<details class="bg-white dark:bg-gray-800 p-4 rounded shadow">
159+
<summary class="font-semibold cursor-pointer">Can I download the formatted JSON?</summary>
160+
<p class="mt-2 text-gray-700 dark:text-gray-300">Yes, after formatting your JSON, you can click the 'Download JSON' button to save the formatted data as a .json file directly to your computer.</p>
161+
</details>
162+
</div>
163+
</section>
164+
165+
<section id="monetization-placeholder" class="text-center mt-16 p-6 bg-yellow-100 dark:bg-yellow-800 dark:text-yellow-100 rounded border border-yellow-300 dark:border-yellow-600">
166+
<h3 class="text-xl font-semibold mb-2">Unlock More Features!</h3>
167+
<p>Upgrade to the Pro Version for features like history saving, cloud synchronization, and more!</p>
168+
<button class="mt-3 bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-2 px-4 rounded transition duration-300">Learn More (Coming Soon)</button>
169+
</section>
170+
</main>
171+
172+
<footer class="text-center p-4 mt-8 text-gray-600 dark:text-gray-400 text-sm">
173+
© <span id="year"></span> JSON Tools. All rights reserved.
174+
</footer>
175+
176+
<script src="script.js"></script> <!-- Common script for dark mode, year, etc. -->
177+
<script src="formatter.js"></script> <!-- Formatter specific script -->
178+
</body>
179+
</html>

formatter.js

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
const jsonInput = document.getElementById('jsonInput');
3+
const jsonOutput = document.getElementById('jsonOutput')?.querySelector('code'); // Target the code element inside pre
4+
const outputPlaceholder = document.getElementById('outputPlaceholder');
5+
const validationError = document.getElementById('validationError');
6+
const formatBtn = document.getElementById('formatBtn');
7+
const minifyBtn = document.getElementById('minifyBtn');
8+
const copyBtn = document.getElementById('copyBtn');
9+
const downloadBtn = document.getElementById('downloadBtn');
10+
const autoFormatCheckbox = document.getElementById('autoFormat');
11+
12+
let currentFormattedJson = ''; // Store the latest valid formatted/minified JSON
13+
14+
const displayOutput = (text, isError = false) => {
15+
if (jsonOutput && outputPlaceholder) {
16+
if (isError || !text) {
17+
jsonOutput.textContent = ''; // Clear output on error or empty
18+
outputPlaceholder.classList.remove('hidden'); // Show placeholder
19+
if (isError) {
20+
validationError.textContent = text;
21+
validationError.classList.remove('hidden');
22+
} else {
23+
validationError.classList.add('hidden');
24+
}
25+
currentFormattedJson = ''; // Reset stored JSON on error
26+
} else {
27+
jsonOutput.textContent = text;
28+
outputPlaceholder.classList.add('hidden'); // Hide placeholder
29+
validationError.classList.add('hidden'); // Hide error message
30+
currentFormattedJson = text; // Store the valid output
31+
}
32+
}
33+
};
34+
35+
const processJson = (minify = false) => {
36+
const rawJson = jsonInput.value.trim();
37+
if (!rawJson) {
38+
displayOutput(''); // Clear output if input is empty
39+
return;
40+
}
41+
42+
try {
43+
const jsonObj = JSON.parse(rawJson);
44+
const outputJson = minify
45+
? JSON.stringify(jsonObj)
46+
: JSON.stringify(jsonObj, null, 4); // Pretty print with 4 spaces
47+
displayOutput(outputJson);
48+
} catch (e) {
49+
// Try to find the error position (basic approach)
50+
let errorMessage = `Invalid JSON: ${e.message}`;
51+
// JSON.parse errors often include position information in modern browsers
52+
// Example: "Unexpected token a in JSON at position 1"
53+
const match = e.message.match(/at position (\d+)/);
54+
if (match && match[1]) {
55+
const position = parseInt(match[1], 10);
56+
// Basic line/col calculation (might not be perfect for all cases)
57+
const textBeforeError = rawJson.substring(0, position);
58+
const lines = textBeforeError.split('\n');
59+
const errorLine = lines.length;
60+
const errorCol = lines[lines.length - 1].length + 1;
61+
errorMessage += ` (around line ${errorLine}, column ${errorCol})`;
62+
}
63+
displayOutput(errorMessage, true);
64+
}
65+
};
66+
67+
if (formatBtn) {
68+
formatBtn.addEventListener('click', () => processJson(false));
69+
}
70+
71+
if (minifyBtn) {
72+
minifyBtn.addEventListener('click', () => processJson(true));
73+
}
74+
75+
if (copyBtn && jsonOutput) {
76+
copyBtn.addEventListener('click', () => {
77+
if (!currentFormattedJson) {
78+
// Maybe provide feedback that there's nothing to copy
79+
console.warn("No valid JSON output to copy.");
80+
return;
81+
}
82+
navigator.clipboard.writeText(currentFormattedJson)
83+
.then(() => {
84+
const originalText = copyBtn.textContent;
85+
copyBtn.textContent = 'Copied!';
86+
setTimeout(() => { copyBtn.textContent = originalText; }, 1500);
87+
})
88+
.catch(err => {
89+
console.error('Failed to copy: ', err);
90+
const originalText = copyBtn.textContent;
91+
copyBtn.textContent = 'Copy Failed';
92+
setTimeout(() => { copyBtn.textContent = originalText; }, 1500);
93+
});
94+
});
95+
}
96+
97+
if (downloadBtn) {
98+
downloadBtn.addEventListener('click', () => {
99+
if (!currentFormattedJson) {
100+
console.warn("No valid JSON output to download.");
101+
// Optionally disable the button or show feedback
102+
return;
103+
}
104+
const blob = new Blob([currentFormattedJson], { type: 'application/json' });
105+
const url = URL.createObjectURL(blob);
106+
const a = document.createElement('a');
107+
a.href = url;
108+
a.download = 'formatted.json'; // Filename
109+
document.body.appendChild(a);
110+
a.click();
111+
document.body.removeChild(a);
112+
URL.revokeObjectURL(url); // Clean up
113+
});
114+
}
115+
116+
// Auto-format on paste
117+
if (jsonInput && autoFormatCheckbox) {
118+
// Load saved preference
119+
const savedAutoFormat = localStorage.getItem('autoFormat') === 'true';
120+
autoFormatCheckbox.checked = savedAutoFormat;
121+
122+
jsonInput.addEventListener('paste', (event) => {
123+
if (autoFormatCheckbox.checked) {
124+
// Prevent default paste to handle it manually
125+
event.preventDefault();
126+
const text = (event.clipboardData || window.clipboardData).getData('text');
127+
jsonInput.value = text; // Set the value first
128+
// Process after a short delay to allow the DOM to update if needed
129+
setTimeout(() => processJson(false), 50);
130+
}
131+
});
132+
133+
// Save preference when checkbox changes
134+
autoFormatCheckbox.addEventListener('change', () => {
135+
localStorage.setItem('autoFormat', autoFormatCheckbox.checked);
136+
});
137+
}
138+
139+
// Initial state setup
140+
displayOutput(''); // Ensure output is clear initially
141+
142+
});

0 commit comments

Comments
 (0)