Skip to content

Commit bd5a693

Browse files
Cleanup
1 parent 9c6d513 commit bd5a693

8 files changed

Lines changed: 825 additions & 780 deletions

File tree

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
11
# muzzard
2-
It downloads files.
2+
It downloads files.
3+
4+
## Structure
5+
6+
- `index.html`: UI markup for all pages in the suite.
7+
- `muzzard.js`: app bootstrap/entrypoint.
8+
- `navigation.js`: single-page navigation (`data-page` links).
9+
- `muzzard-downloader.js`: downloader/import logic for the Muzzard page.
10+
- `cracita.js`: typographic converter module.
11+
- `sorbet.js`: text diff/comparison module.
12+
- `utils.js`: shared browser helpers (`byId`, `sleep`, `debounce`, `throttle`, text/status setters).
13+
14+
## Maintenance notes
15+
16+
- Keep page-specific behavior inside its own module.
17+
- Register all module initializers in `muzzard.js`.
18+
- Reuse `data-page` + `#page-*` naming when adding pages.

cracita.js

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1+
import { byId, createStatusSetter, debounce } from './utils.js';
2+
13
export function initCracita() {
2-
const cracitaPage = document.getElementById('page-cracita');
4+
const cracitaPage = byId('page-cracita');
35
if (!cracitaPage) return;
46

57
const els = {
6-
input: document.getElementById('cracita-inputText'),
7-
output: document.getElementById('cracita-outputText'),
8-
loadBtn: document.getElementById('cracita-loadBtn'),
9-
saveBtn: document.getElementById('cracita-saveBtn'),
10-
copyBtn: document.getElementById('cracita-copyBtn'),
11-
fileInput: document.getElementById('cracita-fileInput'),
12-
status: document.getElementById('cracita-statusField'),
13-
stats: document.getElementById('cracita-statsField'),
14-
mode: document.getElementById('cracita-mode-select'),
15-
regexControls: document.getElementById('cracita-regex-controls'),
16-
regexInput: document.getElementById('cracita-regex-input')
8+
input: byId('cracita-inputText'),
9+
output: byId('cracita-outputText'),
10+
loadBtn: byId('cracita-loadBtn'),
11+
saveBtn: byId('cracita-saveBtn'),
12+
copyBtn: byId('cracita-copyBtn'),
13+
fileInput: byId('cracita-fileInput'),
14+
status: byId('cracita-statusField'),
15+
stats: byId('cracita-statsField'),
16+
mode: byId('cracita-mode-select'),
17+
regexControls: byId('cracita-regex-controls'),
18+
regexInput: byId('cracita-regex-input')
1719
};
18-
19-
let conversionTimer = null;
20+
const setStatus = createStatusSetter(els.status);
2021

2122
const applyTypographicRules = (text) => {
2223
if (!text) return "";
@@ -42,11 +43,11 @@ export function initCracita() {
4243

4344
if (mode === 'Normal') {
4445
output = applyTypographicRules(input);
45-
els.status.textContent = "Auto-converted";
46+
setStatus("Auto-converted");
4647
} else if (mode === 'Regex') {
4748
if (!els.regexInput.value) {
4849
els.output.value = input;
49-
els.status.textContent = "Waiting for pattern...";
50+
setStatus("Waiting for pattern...");
5051
return;
5152
}
5253
try {
@@ -64,10 +65,10 @@ export function initCracita() {
6465
}
6566
return match;
6667
});
67-
els.status.textContent = "Targeted conversion complete.";
68+
setStatus("Targeted conversion complete.");
6869
} catch (e) {
6970
output = input;
70-
els.status.textContent = `Regex error: ${e.message}`;
71+
setStatus(`Regex error: ${e.message}`);
7172
}
7273
}
7374

@@ -81,13 +82,10 @@ export function initCracita() {
8182
els.stats.textContent = `Words: ${wordCount} | Chars: ${text.length}`;
8283
};
8384

84-
const onTextChange = () => {
85-
clearTimeout(conversionTimer);
86-
conversionTimer = setTimeout(() => {
87-
performConversion();
88-
updateStats();
89-
}, 300);
90-
};
85+
const onTextChange = debounce(() => {
86+
performConversion();
87+
updateStats();
88+
}, 300);
9189

9290
els.mode.addEventListener('change', () => {
9391
const isRegex = els.mode.value === 'Regex';
@@ -109,18 +107,18 @@ export function initCracita() {
109107
const blob = new Blob([els.output.value], { type: "text/plain" });
110108
if (typeof saveAs !== 'undefined') {
111109
saveAs(blob, "converted_text.txt");
112-
els.status.textContent = "File saved.";
110+
setStatus("File saved.");
113111
} else {
114112
console.error("FileSaver.js (saveAs) is missing.");
115-
els.status.textContent = "Error: Save dependency missing.";
113+
setStatus("Error: Save dependency missing.");
116114
}
117115
});
118116

119117
els.copyBtn.addEventListener('click', () => {
120118
if (!els.output.value) return;
121119
navigator.clipboard.writeText(els.output.value)
122-
.then(() => els.status.textContent = "Copied to clipboard!")
123-
.catch(() => els.status.textContent = "Copy failed.");
120+
.then(() => setStatus("Copied to clipboard!"))
121+
.catch(() => setStatus("Copy failed."));
124122
});
125123

126124
els.fileInput.addEventListener('change', (e) => {
@@ -130,7 +128,7 @@ export function initCracita() {
130128
reader.onload = (ev) => {
131129
els.input.value = ev.target.result;
132130
onTextChange();
133-
els.status.textContent = `Loaded: ${file.name}`;
131+
setStatus(`Loaded: ${file.name}`);
134132
els.fileInput.value = '';
135133
};
136134
reader.readAsText(file);

index.html

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,36 +86,40 @@ <h1 class="text-3xl font-extrabold text-red-800 font-sans" style="text-shadow: 1
8686

8787
<div class="space-y-4 text-sm leading-relaxed">
8888
<p>
89-
This is <i>muzzard</i>, an utility for downloading images. Paste your direct
89+
This is <i>muzzard</i>, an utility for downloading files in general, including images. Paste your direct
9090
image URLs into the box below (one per line), hit the button, and let it run.
9191
</p>
9292

9393
<textarea id="urls-textarea"
9494
placeholder="e.g. https://i.imgur.com/foobar.jpeg&#10;https://i.imgur.com/example.png"
9595
class="w-full h-48 p-2 border-2 border-black bg-[#fffde7] text-black font-mono text-xs focus:outline-none focus:ring-2 focus:ring-red-700"></textarea>
9696

97-
<div class="flex items-center space-x-6">
98-
<button id="download-btn"
99-
class="px-6 py-2 bg-red-800 text-white font-bold font-sans uppercase tracking-wider border-2 border-black hover:bg-red-900 disabled:bg-gray-500 disabled:cursor-not-allowed transition-colors">
100-
Muzzard it
101-
</button>
102-
<button id="upload-files-btn"
103-
class="px-6 py-2 bg-blue-800 text-white font-bold font-sans uppercase tracking-wider border-2 border-black hover:bg-blue-900 disabled:bg-gray-500 disabled:cursor-not-allowed transition-colors">
104-
Upload files
105-
</button>
106-
<div id="import-text-box" class="flex flex-col items-stretch space-y-2">
107-
<textarea id="import-textarea" rows="2" placeholder="Paste text containing links here"
108-
class="w-56 p-2 border-2 border-black bg-[#fffde7] text-black font-mono text-xs focus:outline-none focus:ring-2 focus:ring-red-700 resize-y"></textarea>
109-
<button type="button" id="import-text-btn"
110-
class="px-2 py-1 bg-yellow-700 text-white font-bold font-sans uppercase tracking-wider border-2 border-black hover:bg-yellow-800 transition-colors">
111-
Paste file/text
97+
<div class="flex flex-col space-y-4">
98+
<div class="flex flex-wrap items-center gap-4">
99+
<button id="download-btn"
100+
class="px-6 py-2 bg-red-800 text-white font-bold font-sans uppercase tracking-wider border-2 border-black hover:bg-red-900 disabled:bg-gray-500 disabled:cursor-not-allowed transition-colors">
101+
Muzzard it
112102
</button>
103+
<button id="upload-files-btn"
104+
class="px-6 py-2 bg-blue-800 text-white font-bold font-sans uppercase tracking-wider border-2 border-black hover:bg-blue-900 disabled:bg-gray-500 disabled:cursor-not-allowed transition-colors">
105+
Upload files
106+
</button>
107+
<label class="flex items-center cursor-pointer">
108+
<input type="checkbox" id="zip-checkbox"
109+
class="h-4 w-4 border-2 border-black bg-[#fffde7] text-red-800 focus:ring-red-700">
110+
<span class="ml-2 text-sm font-bold font-sans">Save as ZIP?</span>
111+
</label>
113112
</div>
114-
<div class="flex items-center">
115-
<input type="checkbox" id="zip-checkbox"
116-
class="h-4 w-4 border-2 border-black bg-[#fffde7] text-red-800 focus:ring-red-700">
117-
<label for="zip-checkbox" class="ml-2 text-sm font-bold font-sans">Save as
118-
ZIP?</label>
113+
<div>
114+
<label for="import-textarea" class="block text-xs font-bold font-sans mb-2">Or paste links/text:</label>
115+
<div class="flex gap-2">
116+
<textarea id="import-textarea" rows="2" placeholder="Paste text containing links here"
117+
class="flex-1 p-2 border-2 border-black bg-[#fffde7] text-black font-mono text-xs focus:outline-none focus:ring-2 focus:ring-red-700 resize-y"></textarea>
118+
<button type="button" id="import-text-btn"
119+
class="px-4 py-2 bg-yellow-700 text-white font-bold font-sans uppercase tracking-wider border-2 border-black hover:bg-yellow-800 transition-colors whitespace-nowrap">
120+
Import
121+
</button>
122+
</div>
119123
</div>
120124
</div>
121125

@@ -125,7 +129,7 @@ <h1 class="text-3xl font-extrabold text-red-800 font-sans" style="text-shadow: 1
125129
line.</p>
126130
</div>
127131
<p class="text-xs italic">
128-
Note: muzzard works best with direct image links (e.g., Imgur direct links). It may not
132+
Note: muzzard works best with direct image links (e.g., https://i.imgur.com/example.jpeg). It may not
129133
work with all sites due to CORS or hotlink protection.
130134
</p>
131135
</div>
@@ -135,8 +139,8 @@ <h1 class="text-3xl font-extrabold text-red-800 font-sans" style="text-shadow: 1
135139
<h1 class="text-3xl font-extrabold text-red-800 font-sans" style="text-shadow: 1px 1px 0 #000">About
136140
Muzzard</h1>
137141
<div class="space-y-4 text-sm leading-relaxed">
138-
<p>There's not really much to say about muzzard. It's a simple tool with one
139-
purpose: to download images from the web quickly and without fuss. But like any good tool,
142+
<p>There's not really much to say about muzzard. This is a simple tool with one
143+
purpose: to download files from a source quickly and without much fuss. But like any good tool,
140144
it's got a bit of personality.</p>
141145
<p>This site's design is a homage to Hunter S. Thompson's "Hey, Rube!" column on ESPN's
142146
Page 2, and also to the at times eccentric web design of the 2000s.</p>
@@ -152,7 +156,7 @@ <h1 class="text-3xl font-extrabold text-red-800 font-sans" style="text-shadow: 1
152156
style="text-shadow: 1px 1px 0 #000">How to use Muzzard</h2>
153157
<p>It's simple, by design. I think.</p>
154158
<ol class="list-decimal list-inside space-y-2 pl-4">
155-
<li>Find the direct URL to an image you want to download. This usually ends in .jpg, .png,
159+
<li>Find the direct URL to a file you want to download. This usually ends in .jpg, .png,
156160
.gif, etc.</li>
157161
<li>Paste the URL into the big text box on the homepage.</li>
158162
<li>If you have more than one, paste each URL on a new line.</li>

0 commit comments

Comments
 (0)