@@ -7,6 +7,13 @@ import Layout from "../layouts/Layout.astro"
77 <h1 >Auto Source</h1 >
88 <p >Generate RSS feeds from any website automatically</p >
99
10+ <div class =" bookmarklet-section" >
11+ <h3 >📌 Quick Access Bookmarklet</h3 >
12+ <p >Drag this button to your bookmarks bar to quickly convert any website to RSS:</p >
13+ <a id =" bookmarklet" class =" btn btn-bookmarklet" href =" #" >📰 Convert to RSS</a >
14+ <p class =" bookmarklet-help" >Click the button above to generate the bookmarklet, then drag it to your bookmarks bar.</p >
15+ </div >
16+
1017 <div class =" auto-source-form" >
1118 <form id =" auto-source-form" novalidate >
1219 <div class =" form-group" >
@@ -70,6 +77,8 @@ import Layout from "../layouts/Layout.astro"
7077 <li >Use the generated URL in your RSS reader</li >
7178 </ul >
7279
80+ <p ><a href =" /auto-source-instructions/" class =" btn btn-secondary" >📖 View Detailed Instructions</a ></p >
81+
7382 <div class =" restrictions" >
7483 <h4 >⚠️ URL Restrictions</h4 >
7584 <p >
@@ -87,28 +96,80 @@ import Layout from "../layouts/Layout.astro"
8796</Layout >
8897
8998<script >
90- document.getElementById("auto-source-form").addEventListener("submit", async (e) => {
99+ // Bookmarklet functionality
100+ function initBookmarklet() {
101+ const bookmarklet = document.getElementById("bookmarklet") as HTMLAnchorElement;
102+ if (!bookmarklet) return;
103+
104+ bookmarklet.href = generateBookmarkletHref();
105+ }
106+
107+ function generateBookmarkletHref() {
108+ const baseUrl = new URL(window.location.origin);
109+ baseUrl.pathname = "auto_source/";
110+ baseUrl.search = "?url=";
111+ baseUrl.hash = "";
112+
113+ return `javascript:window.location.href='${baseUrl.toString()}'+window.location.href;`;
114+ }
115+
116+ // Initialize bookmarklet on page load
117+ initBookmarklet();
118+
119+ // Handle URL parameters from bookmarklet
120+ function handleUrlParams() {
121+ const params = new URLSearchParams(window.location.search);
122+ const url = params.get("url");
123+ const strategy = params.get("strategy");
124+
125+ if (url) {
126+ const urlInput = document.getElementById("url") as HTMLInputElement;
127+ const strategySelect = document.getElementById("strategy") as HTMLSelectElement;
128+
129+ if (urlInput) urlInput.value = url;
130+ if (strategy && strategySelect) strategySelect.value = strategy;
131+
132+ // Auto-submit if URL is provided
133+ if (urlInput && urlInput.value) {
134+ const form = document.getElementById("auto-source-form") as HTMLFormElement;
135+ if (form) {
136+ form.dispatchEvent(new Event("submit"));
137+ }
138+ }
139+ }
140+ }
141+
142+ // Handle URL parameters on page load
143+ handleUrlParams();
144+
145+ document.getElementById("auto-source-form")?.addEventListener("submit", async (e) => {
91146 e.preventDefault()
92147
93- const formData = new FormData(e.target)
94- const url = formData.get("url")
95- const strategy = formData.get("strategy")
148+ const form = e.target as HTMLFormElement
149+ const formData = new FormData(form)
150+ const url = formData.get("url") as string
151+ const strategy = formData.get("strategy") as string
96152
97153 if (!url) return
98154
155+ // Show loading state
156+ const submitBtn = form.querySelector('button[type="submit"]') as HTMLButtonElement
157+ const originalText = submitBtn.textContent
158+
99159 try {
100- // Show loading state
101- const submitBtn = e.target.querySelector('button[type="submit"]')
102- const originalText = submitBtn.textContent
103160 submitBtn.textContent = "Generating..."
104161 submitBtn.disabled = true
105162
106163 // Encode URL for API
107164 const encodedUrl = btoa(url)
108- const apiUrl = `http://localhost:3000 /auto_source/${encodedUrl}?strategy=${strategy}`
165+ const apiUrl = `http://127.0.0.1:3001 /auto_source/${encodedUrl}?strategy=${strategy}`
109166
110- // Test the API call
111- const response = await fetch(apiUrl)
167+ // Test the API call with Basic authentication
168+ const response = await fetch(apiUrl, {
169+ headers: {
170+ 'Authorization': 'Basic ' + btoa('admin:password')
171+ }
172+ })
112173
113174 if (!response.ok) {
114175 throw new Error(`API call failed: ${response.status} ${response.statusText}`)
@@ -117,20 +178,20 @@ import Layout from "../layouts/Layout.astro"
117178 // Show result area
118179 const resultArea = document.getElementById("result")
119180 const feedUrlSpan = document.getElementById("feed-url")
120- const subscribeLink = document.getElementById("subscribe-link")
181+ const subscribeLink = document.getElementById("subscribe-link") as HTMLAnchorElement
121182
122- feedUrlSpan.textContent = apiUrl
123- subscribeLink.href = apiUrl
124- resultArea.style.display = "block"
125-
126- // Scroll to result
127- resultArea.scrollIntoView({ behavior: "smooth" })
183+ if (feedUrlSpan) feedUrlSpan.textContent = apiUrl
184+ if (subscribeLink) subscribeLink.href = apiUrl
185+ if ( resultArea) {
186+ resultArea.style.display = "block"
187+ resultArea.scrollIntoView({ behavior: "smooth" })
188+ }
128189 } catch (error) {
129190 console.error("Error generating feed:", error)
130191 showError(`Error generating feed: ${error.message}`)
131192 } finally {
132193 // Reset button state
133- const submitBtn = e.target. querySelector('button[type="submit"]')
194+ const submitBtn = form. querySelector('button[type="submit"]') as HTMLButtonElement
134195 submitBtn.textContent = originalText
135196 submitBtn.disabled = false
136197 }
@@ -142,18 +203,55 @@ import Layout from "../layouts/Layout.astro"
142203 const resultArea = document.getElementById("result")
143204
144205 // Hide result area
145- resultArea.style.display = "none"
206+ if (resultArea) resultArea.style.display = "none"
146207
147208 // Show error area
148- errorMessage.textContent = message
149- errorArea.style.display = "block"
150-
151- // Scroll to error
152- errorArea.scrollIntoView({ behavior: "smooth" })
209+ if (errorMessage) errorMessage.textContent = message
210+ if ( errorArea) {
211+ errorArea.style.display = "block"
212+ errorArea.scrollIntoView({ behavior: "smooth" })
213+ }
153214 }
154215</script >
155216
156217<style >
218+ .bookmarklet-section {
219+ max-width: 600px;
220+ margin: 2rem 0;
221+ padding: 1.5rem;
222+ background: #f8f9fa;
223+ border: 1px solid #dee2e6;
224+ border-radius: 8px;
225+ }
226+
227+ .bookmarklet-section h3 {
228+ margin: 0 0 1rem 0;
229+ color: #495057;
230+ }
231+
232+ .bookmarklet-section p {
233+ margin: 0.5rem 0;
234+ color: #6c757d;
235+ }
236+
237+ .btn-bookmarklet {
238+ background: #28a745;
239+ font-size: 1.1rem;
240+ padding: 0.75rem 1.5rem;
241+ margin: 1rem 0;
242+ display: inline-block;
243+ }
244+
245+ .btn-bookmarklet:hover {
246+ background: #218838;
247+ }
248+
249+ .bookmarklet-help {
250+ font-size: 0.875rem;
251+ font-style: italic;
252+ color: #6c757d;
253+ }
254+
157255 .auto-source-form {
158256 max-width: 600px;
159257 margin: 2rem 0;
0 commit comments