@@ -16,39 +16,72 @@ function getDefaultInstanceUrl() {
1616 return atob ( 'aHR0cHM6Ly8xLmgyci53b3JrZXJzLmRldi8=' ) ;
1717}
1818
19+ function getStorageKey ( ) {
20+ return 'html2rss.feedDirectory.instanceUrl' ;
21+ }
22+
1923function getHashParams ( ) {
2024 const hash = window . location . hash || '' ;
21- const normalizedHash = hash . startsWith ( '#!' ) ? hash . slice ( 2 ) : hash . startsWith ( '#' ) ? hash . slice ( 1 ) : hash ;
22- return new URLSearchParams ( normalizedHash ) ;
25+ if ( ! hash . startsWith ( '#!' ) ) return new URLSearchParams ( ) ;
26+ return new URLSearchParams ( hash . slice ( 2 ) ) ;
27+ }
28+
29+ function normalizeParsedInstanceUrl ( parsedUrl ) {
30+ if ( parsedUrl . protocol !== 'http:' && parsedUrl . protocol !== 'https:' ) {
31+ return null ;
32+ }
33+
34+ parsedUrl . search = '' ;
35+ parsedUrl . hash = '' ;
36+ return parsedUrl . toString ( ) ;
2337}
2438
2539function readInstanceUrlFromHash ( defaultInstanceUrl ) {
2640 const candidate = getHashParams ( ) . get ( 'url' ) ;
2741 if ( ! candidate ) return defaultInstanceUrl ;
2842
2943 try {
30- const parsedUrl = new URL ( candidate ) ;
31- parsedUrl . search = '' ;
32- parsedUrl . hash = '' ;
33- return parsedUrl . toString ( ) ;
44+ return normalizeParsedInstanceUrl ( new URL ( candidate ) ) || defaultInstanceUrl ;
3445 } catch {
3546 return defaultInstanceUrl ;
3647 }
3748}
3849
39- function writeInstanceUrlToHash ( instanceUrl , defaultInstanceUrl ) {
40- const params = getHashParams ( ) ;
41- if ( instanceUrl && instanceUrl !== defaultInstanceUrl ) {
42- params . set ( 'url' , instanceUrl ) ;
43- } else {
44- params . delete ( 'url' ) ;
50+ function readInstanceUrlFromStorage ( defaultInstanceUrl ) {
51+ try {
52+ const candidate = window . localStorage . getItem ( getStorageKey ( ) ) ;
53+ if ( ! candidate ) return defaultInstanceUrl ;
54+ return normalizeInstanceUrl ( candidate ) || defaultInstanceUrl ;
55+ } catch {
56+ return defaultInstanceUrl ;
4557 }
58+ }
4659
47- const nextHash = params . toString ( ) ;
48- const nextUrl = nextHash
49- ? `${ window . location . pathname } ${ window . location . search } #!${ nextHash } `
50- : `${ window . location . pathname } ${ window . location . search } ` ;
51- window . history . replaceState ( { } , '' , nextUrl ) ;
60+ function writeInstanceUrl ( instanceUrl , defaultInstanceUrl ) {
61+ try {
62+ if ( instanceUrl && instanceUrl !== defaultInstanceUrl ) {
63+ window . localStorage . setItem ( getStorageKey ( ) , instanceUrl ) ;
64+ } else {
65+ window . localStorage . removeItem ( getStorageKey ( ) ) ;
66+ }
67+ } catch {
68+ // Ignore storage failures and keep the current page usable.
69+ }
70+
71+ if ( window . location . hash . startsWith ( '#!' ) ) {
72+ const nextUrl = `${ window . location . pathname } ${ window . location . search } ` ;
73+ window . history . replaceState ( { } , '' , nextUrl ) ;
74+ }
75+ }
76+
77+ function readInitialInstanceUrl ( defaultInstanceUrl ) {
78+ const hashInstanceUrl = readInstanceUrlFromHash ( defaultInstanceUrl ) ;
79+ if ( hashInstanceUrl !== defaultInstanceUrl ) {
80+ writeInstanceUrl ( hashInstanceUrl , defaultInstanceUrl ) ;
81+ return hashInstanceUrl ;
82+ }
83+
84+ return readInstanceUrlFromStorage ( defaultInstanceUrl ) ;
5285}
5386
5487function fuzzyMatch ( text , query ) {
@@ -78,10 +111,7 @@ function normalizeInstanceUrl(value) {
78111 if ( ! trimmed ) return null ;
79112
80113 try {
81- const parsedUrl = new URL ( trimmed ) ;
82- parsedUrl . search = '' ;
83- parsedUrl . hash = '' ;
84- return parsedUrl . toString ( ) ;
114+ return normalizeParsedInstanceUrl ( new URL ( trimmed ) ) ;
85115 } catch {
86116 return null ;
87117 }
@@ -195,6 +225,11 @@ function setupInstanceEditor(
195225 const apply = document . querySelector ( '[data-apply-instance]' ) ;
196226 if ( ! toggle || ! editor || ! input || ! apply ) return ;
197227
228+ const directory = document . querySelector ( '[data-feed-directory]' ) ;
229+ if ( directory ) {
230+ directory . dataset . enhanced = 'true' ;
231+ }
232+
198233 const setExpanded = ( expanded ) => {
199234 editor . hidden = ! expanded ;
200235 toggle . setAttribute ( 'aria-expanded' , String ( expanded ) ) ;
@@ -222,12 +257,14 @@ function setupInstanceEditor(
222257 setCurrentInstanceUrl ( normalized ) ;
223258 input . value = normalized ;
224259 updateInstanceSummary ( normalized ) ;
225- writeInstanceUrlToHash ( normalized , defaultInstanceUrl ) ;
260+ writeInstanceUrl ( normalized , defaultInstanceUrl ) ;
226261 updateFeedUrls ( normalized ) ;
227262 setExpanded ( false ) ;
228263 setInstanceFeedback ( 'Using your custom instance.' , 'success' ) ;
229264 } ;
230265
266+ setExpanded ( false ) ;
267+
231268 apply . addEventListener ( 'click' , applyInstance ) ;
232269 input . addEventListener ( 'keydown' , ( event ) => {
233270 if ( event . key === 'Enter' ) {
@@ -313,7 +350,7 @@ function setupCopyButtons() {
313350
314351function initializeFeedDirectory ( ) {
315352 const defaultInstanceUrl = getDefaultInstanceUrl ( ) ;
316- let currentInstanceUrl = readInstanceUrlFromHash ( defaultInstanceUrl ) ;
353+ let currentInstanceUrl = readInitialInstanceUrl ( defaultInstanceUrl ) ;
317354 const searchInput = document . getElementById ( 'search-input' ) ;
318355 const feedItems = Array . from ( document . querySelectorAll ( '[data-domain]' ) ) ;
319356 const instanceInput = document . getElementById ( 'instance-url-input' ) ;
0 commit comments