webring-rails 1.4.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bad76f5ea0fcb10729377a5cc42b2bc858a1460d929ca0711e490d26822dfe5e
4
- data.tar.gz: 72995b854fdcaeeea0e710ad3a7deaa5fd101e1e87365d50a822ac439f89ce01
3
+ metadata.gz: fab197d616f0b7c93d8689e4873d66fc86c186af7401dbd7237ba00cfeef5dcf
4
+ data.tar.gz: 9770538896f190f67b28d796b3ec58618cedb4a763f42833d610253754b8ce34
5
5
  SHA512:
6
- metadata.gz: ee9b231f41c8165590650ff6fce9ef53f7eb48660195a39cf9592eeeef698d59eb9bc61b3ab39231785978ee8f8263fa6a0b9938893f48132c6928c3e9cbefdb
7
- data.tar.gz: 82f951215f76f067ca9023c27e7665e56e7399894ec597db46ed598d02e84c470c6e5da6ee9457de93b29050a61ab42b71a8de32c512d28c3f62dbd21f6d648a
6
+ metadata.gz: a5827a69ce17c27f9f3ecdfb7c5bcf295e49dd2a2b3466698cc51287c77d888df2de53d6ac4eaa0b69818fb1528161a6ad13973339c17f20f0819ca430258181
7
+ data.tar.gz: 62e1d083641d38151c2787c992cccbc652ee090fb6075462f38ccfab3bce64c8dd5aa7a21710b2ddde676fedabdc4ff0b29bf7efeae7819271406df32aebfd84
@@ -112,6 +112,85 @@
112
112
  });
113
113
 
114
114
  const STYLES = Object.freeze({
115
+ // Reset all generic element selectors except SVG (to preserve SVG functionality)
116
+ reset: `
117
+ .webring-nav,
118
+ .webring-nav div,
119
+ .webring-nav span,
120
+ .webring-nav nav,
121
+ .webring-nav a,
122
+ .webring-nav div::before,
123
+ .webring-nav span::before,
124
+ .webring-nav nav::before,
125
+ .webring-nav a::before,
126
+ .webring-nav div::after,
127
+ .webring-nav span::after,
128
+ .webring-nav nav::after,
129
+ .webring-nav a::after {
130
+ all: initial;
131
+ box-sizing: border-box;
132
+ }
133
+
134
+ .webring-nav,
135
+ .webring-nav div,
136
+ .webring-nav span,
137
+ .webring-nav nav,
138
+ .webring-nav a {
139
+ font-family: inherit;
140
+ font-size: inherit;
141
+ line-height: inherit;
142
+ color: inherit;
143
+ }
144
+
145
+ .webring-nav div,
146
+ .webring-nav span,
147
+ .webring-nav nav,
148
+ .webring-nav a {
149
+ display: initial;
150
+ margin: 0;
151
+ padding: 0;
152
+ border: none;
153
+ background: none;
154
+ text-decoration: none;
155
+ color: inherit;
156
+ font-weight: inherit;
157
+ font-size: inherit;
158
+ line-height: inherit;
159
+ vertical-align: baseline;
160
+ box-shadow: none;
161
+ outline: none;
162
+ transform: none;
163
+ opacity: 1;
164
+ visibility: visible;
165
+ position: static;
166
+ float: none;
167
+ clear: none;
168
+ overflow: visible;
169
+ white-space: normal;
170
+ text-align: left;
171
+ letter-spacing: normal;
172
+ word-spacing: normal;
173
+ text-transform: none;
174
+ text-shadow: none;
175
+ list-style: none;
176
+ border-radius: 0;
177
+ min-width: auto;
178
+ max-width: none;
179
+ min-height: auto;
180
+ max-height: none;
181
+ width: auto;
182
+ height: auto;
183
+ top: auto;
184
+ right: auto;
185
+ bottom: auto;
186
+ left: auto;
187
+ z-index: auto;
188
+ }
189
+
190
+ .webring-nav a {
191
+ cursor: pointer;
192
+ }
193
+ `,
115
194
  layout: `
116
195
  .webring-nav {
117
196
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
@@ -122,9 +201,14 @@
122
201
  max-width: 350px;
123
202
  margin: 0 auto;
124
203
  padding: 10px;
204
+ box-sizing: border-box;
125
205
  }
126
- .webring-title {
206
+ .webring-nav .webring-title {
127
207
  margin-bottom: 8px;
208
+ margin-top: 0;
209
+ padding: 0;
210
+ font-size: inherit;
211
+ line-height: normal;
128
212
  }
129
213
  .webring-nav nav {
130
214
  display: flex;
@@ -132,19 +216,25 @@
132
216
  width: 100%;
133
217
  justify-content: center;
134
218
  align-items: center;
219
+ margin: 0;
220
+ padding: 0;
221
+ box-sizing: border-box;
135
222
  }
136
- .webring-btn {
223
+ .webring-nav .webring-btn {
137
224
  display: flex;
138
225
  align-items: center;
139
226
  justify-content: center;
140
227
  padding: 6px 12px;
141
228
  text-decoration: none;
229
+ box-sizing: border-box;
230
+ margin: 0;
142
231
  }
143
- .random-btn {
232
+ .webring-nav .webring-btn.random-btn {
144
233
  padding: 6px 8px;
145
234
  }
146
- .logo-only {
235
+ .webring-nav nav .logo-only {
147
236
  padding: 8px 3px 6px 3px;
237
+ margin: 0;
148
238
  }
149
239
  .webring-nav[data-widget-type="no-text"] {
150
240
  padding: 8px 10px;
@@ -152,17 +242,19 @@
152
242
  .webring-nav[data-widget-type="one-way"] {
153
243
  max-width: 200px;
154
244
  }
155
- .webring-logo-inline {
245
+ .webring-nav .webring-logo-inline {
156
246
  display: inline-block;
157
247
  vertical-align: middle;
158
248
  margin-right: 6px;
159
249
  margin-top: 1px;
250
+ margin-bottom: 0;
251
+ margin-left: 0;
160
252
  }
161
- [data-button-text="false"] .prev-btn {
253
+ .webring-nav[data-button-text="false"] .prev-btn {
162
254
  padding-top: 5px;
163
255
  padding-right: 12.5px;
164
256
  }
165
- [data-button-text="false"] .next-btn {
257
+ .webring-nav[data-button-text="false"] .next-btn {
166
258
  padding-top: 5px;
167
259
  padding-left: 12.5px;
168
260
  }
@@ -171,10 +263,10 @@
171
263
  .webring-nav[data-widget-type="full"] {
172
264
  border: 2.5px solid #000000;
173
265
  }
174
- .webring-title {
266
+ .webring-nav .webring-title {
175
267
  font-weight: 600;
176
268
  }
177
- .webring-btn {
269
+ .webring-nav .webring-btn {
178
270
  text-wrap: nowrap;
179
271
  color: #000000;
180
272
  font-weight: 600;
@@ -182,16 +274,16 @@
182
274
  border: 2.5px solid #000000;
183
275
  transition: background-color 0.2s ease, color 0.2s ease;
184
276
  }
185
- .webring-btn:hover {
277
+ .webring-nav .webring-btn:hover {
186
278
  background-color: #000000;
187
279
  color: #ffffff;
188
280
  }
189
- .webring-btn:focus {
281
+ .webring-nav .webring-btn:focus {
190
282
  outline: none;
191
283
  background-color: transparent;
192
284
  color: #000000;
193
285
  }
194
- .webring-btn:active {
286
+ .webring-nav .webring-btn:active {
195
287
  border-color: #000000;
196
288
  background-color: #000000;
197
289
  color: #ffffff;
@@ -340,13 +432,14 @@
340
432
 
341
433
  switch (styleOption) {
342
434
  case 'none':
343
- styleElement.textContent = '';
435
+ // Even with 'none', apply reset to protect against host styles
436
+ styleElement.textContent = STYLES.reset;
344
437
  break;
345
438
  case 'layout':
346
- styleElement.textContent = STYLES.layout;
439
+ styleElement.textContent = STYLES.reset + STYLES.layout;
347
440
  break;
348
441
  default: // 'full'
349
- styleElement.textContent = STYLES.layout + STYLES.design;
442
+ styleElement.textContent = STYLES.reset + STYLES.layout + STYLES.design;
350
443
  }
351
444
  }
352
445
 
@@ -1 +1 @@
1
- !function(){function e(e){function n(e){let n=document.getElementById(t.STYLE_ID);switch(n||(n=document.createElement("style"),n.id=t.STYLE_ID,document.head.appendChild(n)),e){case"none":n.textContent="";break;case"layout":n.textContent=s.layout;break;default:n.textContent=s.layout+s.design}}const o=e||document.currentScript||document.getElementsByTagName("script")[document.getElementsByTagName("script").length-1];if(!o)return;const a=o.getAttribute("data-member-uid"),g=o.getAttribute("data-widget-type")??t.DEFAULT_TYPE,p=o.getAttribute("data-target-id")??t.DEFAULT_TARGET_ID,f="false"!==o.getAttribute("data-button-text"),u=o.getAttribute("data-styles")??t.DEFAULT_STYLE_TYPE,x=t.VALID_STYLE_TYPES.includes(u)?u:t.DEFAULT_STYLE_TYPE,b=o.getAttribute("data-prev-text"),m=o.getAttribute("data-random-text"),w=o.getAttribute("data-next-text"),y=o.getAttribute("data-widget-text");if(!a)return void console.error("Webring Widget: Missing data-member-uid attribute on script tag.");if(!t.VALID_TYPES.includes(g))return void console.error(`Webring Widget: Invalid widget type "${g}". Valid types: ${t.VALID_TYPES.join(", ")}`);const T=o.getAttribute("src"),E=new URL(T,window.location.href).origin,_=function(){const e=document.getElementById(p);if(!e)return void console.error(`Webring Widget: No element with id "${p}" found.`);c||(n(x),c=!0);const t=document.createDocumentFragment(),o=document.createElement("div");o.className="webring-nav",o.setAttribute("data-widget-type",g),o.setAttribute("data-button-text",f.toString());const s={prev:d.prev.text_enforced?d.prev:b?{...d.prev,text:`\xab ${b}`}:d.prev,random:d.random.text_enforced?d.random:m?{...d.random,text:`${r(20,20,"margin-right: 4px; margin-top: 1px;")} ${m}`}:d.random,next:d.next.text_enforced?d.next:w?{...d.next,text:`${w} \xbb`}:d.next,logoOnly:d.logoOnly},u=l[g];if(u.showTitle){const e=document.createElement("span");e.className="webring-title",e.innerHTML=i.widgetTitle.enforced?i.widgetTitle.default:y??i.widgetTitle.default,o.appendChild(e)}const T=document.createElement("nav");T.className="webring-buttons",u.actions.forEach((e=>{const t=s[e];if("logoOnly"===e){const e=document.createElement("div");return e.className=t.additionalClass,e.innerHTML=t.symbol,void T.appendChild(e)}const n=document.createElement("a");if(n.href=`${E}/webring/${t.path}?source_member_uid=${a}`,n.title=t.title,n.className=`webring-btn ${t.additionalClass}`,"one-way"===g&&u.showLogoInButton&&"next"===e){const e=d.next.text_enforced?i.next.default:w||s.next.text.replace(" \xbb","");n.innerHTML=f?`<span class="webring-logo-inline">${r(20,20)}</span> ${e} \xbb`:`<span class="webring-logo-inline">${r(20,20)}</span> ${t.symbol}`}else n.innerHTML=f?t.text:t.symbol;T.appendChild(n)})),o.appendChild(T),t.appendChild(o),e.innerHTML="",e.appendChild(t)};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",_):_()}const t=Object.freeze({VALID_TYPES:Object.freeze(["full","no-text","two-way","one-way","random-only"]),DEFAULT_TYPE:"full",DEFAULT_TARGET_ID:"webring-widget",STYLE_ID:"webring-widget-styles",VALID_STYLE_TYPES:Object.freeze(["full","layout","none"]),DEFAULT_STYLE_TYPE:"full"}),n=Object.freeze({prev:{default:"\xab Prev",enforced:!1},random:{default:"Random",enforced:!1},next:{default:"Next \xbb",enforced:!1},widgetTitle:{default:"Webring",enforced:!1}}),o="<<REPLACE_ME_TEXT_DEFAULTS>>",a="<<REPLACE_ME_TEXT_DEFAULTS>>"!==o?"string"==typeof o?JSON.parse(o):o:{},i=Object.freeze(Object.keys(n).reduce(((e,t)=>{const o=a[t];return e[t]={default:o?.default??n[t].default,enforced:o?.enforced??n[t].enforced},e}),{})),r="<<REPLACE_ME_LOGO_SVG_FUNCTION>>",d=Object.freeze({prev:{symbol:"\xab",text:`\xab ${i.prev.default}`,text_enforced:i.prev.enforced,title:"Previous site",path:"previous",additionalClass:"prev-btn"},random:{symbol:r(23,23),text:`${r(20,20,"margin-right: 4px; margin-top: 1px;")} ${i.random.default}`,text_enforced:i.random.enforced,title:"Random site",path:"random",additionalClass:"random-btn"},next:{symbol:"\xbb",text:`${i.next.default} \xbb`,text_enforced:i.next.enforced,title:"Next site",path:"next",additionalClass:"next-btn"},logoOnly:{symbol:r(23,23),text:r(23,23),path:"",additionalClass:"logo-only"}}),l=Object.freeze({full:{showTitle:!0,actions:["prev","random","next"]},"no-text":{showTitle:!1,actions:["prev","random","next"]},"two-way":{showTitle:!1,actions:["prev","logoOnly","next"],showLogoInMiddle:!0},"one-way":{showTitle:!1,actions:["next"],showLogoInButton:!0},"random-only":{showTitle:!1,actions:["random"]}}),s=Object.freeze({layout:'\n .webring-nav {\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;\n font-size: 16px;\n display: flex;\n flex-direction: column;\n align-items: center;\n max-width: 350px;\n margin: 0 auto;\n padding: 10px;\n }\n .webring-title {\n margin-bottom: 8px;\n }\n .webring-nav nav {\n display: flex;\n gap: 10px;\n width: 100%;\n justify-content: center;\n align-items: center;\n }\n .webring-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px 12px;\n text-decoration: none;\n }\n .random-btn {\n padding: 6px 8px;\n }\n .logo-only {\n padding: 8px 3px 6px 3px;\n }\n .webring-nav[data-widget-type="no-text"] {\n padding: 8px 10px;\n }\n .webring-nav[data-widget-type="one-way"] {\n max-width: 200px;\n }\n .webring-logo-inline {\n display: inline-block;\n vertical-align: middle;\n margin-right: 6px;\n margin-top: 1px;\n }\n [data-button-text="false"] .prev-btn {\n padding-top: 5px;\n padding-right: 12.5px;\n }\n [data-button-text="false"] .next-btn {\n padding-top: 5px;\n padding-left: 12.5px;\n }\n ',design:'\n .webring-nav[data-widget-type="full"] {\n border: 2.5px solid #000000;\n }\n .webring-title {\n font-weight: 600;\n }\n .webring-btn {\n text-wrap: nowrap;\n color: #000000;\n font-weight: 600;\n background-color: #ffffff;\n border: 2.5px solid #000000;\n transition: background-color 0.2s ease, color 0.2s ease;\n }\n .webring-btn:hover {\n background-color: #000000;\n color: #ffffff;\n }\n .webring-btn:focus {\n outline: none;\n background-color: transparent;\n color: #000000;\n }\n .webring-btn:active {\n border-color: #000000;\n background-color: #000000;\n color: #ffffff;\n }\n '});let c=!1;e()}();
1
+ !function(){function n(n){function t(n){let t=document.getElementById(e.STYLE_ID);switch(t||(t=document.createElement("style"),t.id=e.STYLE_ID,document.head.appendChild(t)),n){case"none":t.textContent=g.reset;break;case"layout":t.textContent=g.reset+g.layout;break;default:t.textContent=g.reset+g.layout+g.design}}const i=n||document.currentScript||document.getElementsByTagName("script")[document.getElementsByTagName("script").length-1];if(!i)return;const a=i.getAttribute("data-member-uid"),b=i.getAttribute("data-widget-type")??e.DEFAULT_TYPE,c=i.getAttribute("data-target-id")??e.DEFAULT_TARGET_ID,p="false"!==i.getAttribute("data-button-text"),f=i.getAttribute("data-styles")??e.DEFAULT_STYLE_TYPE,w=e.VALID_STYLE_TYPES.includes(f)?f:e.DEFAULT_STYLE_TYPE,m=i.getAttribute("data-prev-text"),u=i.getAttribute("data-random-text"),x=i.getAttribute("data-next-text"),v=i.getAttribute("data-widget-text");if(!a)return void console.error("Webring Widget: Missing data-member-uid attribute on script tag.");if(!e.VALID_TYPES.includes(b))return void console.error(`Webring Widget: Invalid widget type "${b}". Valid types: ${e.VALID_TYPES.join(", ")}`);const h=i.getAttribute("src"),y=new URL(h,window.location.href).origin,T=function(){const n=document.getElementById(c);if(!n)return void console.error(`Webring Widget: No element with id "${c}" found.`);s||(t(w),s=!0);const e=document.createDocumentFragment(),i=document.createElement("div");i.className="webring-nav",i.setAttribute("data-widget-type",b),i.setAttribute("data-button-text",p.toString());const g={prev:d.prev.text_enforced?d.prev:m?{...d.prev,text:`\xab ${m}`}:d.prev,random:d.random.text_enforced?d.random:u?{...d.random,text:`${r(20,20,"margin-right: 4px; margin-top: 1px;")} ${u}`}:d.random,next:d.next.text_enforced?d.next:x?{...d.next,text:`${x} \xbb`}:d.next,logoOnly:d.logoOnly},f=l[b];if(f.showTitle){const n=document.createElement("span");n.className="webring-title",n.innerHTML=o.widgetTitle.enforced?o.widgetTitle.default:v??o.widgetTitle.default,i.appendChild(n)}const h=document.createElement("nav");h.className="webring-buttons",f.actions.forEach((n=>{const e=g[n];if("logoOnly"===n){const n=document.createElement("div");return n.className=e.additionalClass,n.innerHTML=e.symbol,void h.appendChild(n)}const t=document.createElement("a");if(t.href=`${y}/webring/${e.path}?source_member_uid=${a}`,t.title=e.title,t.className=`webring-btn ${e.additionalClass}`,"one-way"===b&&f.showLogoInButton&&"next"===n){const n=d.next.text_enforced?o.next.default:x||g.next.text.replace(" \xbb","");t.innerHTML=p?`<span class="webring-logo-inline">${r(20,20)}</span> ${n} \xbb`:`<span class="webring-logo-inline">${r(20,20)}</span> ${e.symbol}`}else t.innerHTML=p?e.text:e.symbol;h.appendChild(t)})),i.appendChild(h),e.appendChild(i),n.innerHTML="",n.appendChild(e)};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",T):T()}const e=Object.freeze({VALID_TYPES:Object.freeze(["full","no-text","two-way","one-way","random-only"]),DEFAULT_TYPE:"full",DEFAULT_TARGET_ID:"webring-widget",STYLE_ID:"webring-widget-styles",VALID_STYLE_TYPES:Object.freeze(["full","layout","none"]),DEFAULT_STYLE_TYPE:"full"}),t=Object.freeze({prev:{default:"\xab Prev",enforced:!1},random:{default:"Random",enforced:!1},next:{default:"Next \xbb",enforced:!1},widgetTitle:{default:"Webring",enforced:!1}}),i="<<REPLACE_ME_TEXT_DEFAULTS>>",a="<<REPLACE_ME_TEXT_DEFAULTS>>"!==i?"string"==typeof i?JSON.parse(i):i:{},o=Object.freeze(Object.keys(t).reduce(((n,e)=>{const i=a[e];return n[e]={default:i?.default??t[e].default,enforced:i?.enforced??t[e].enforced},n}),{})),r="<<REPLACE_ME_LOGO_SVG_FUNCTION>>",d=Object.freeze({prev:{symbol:"\xab",text:`\xab ${o.prev.default}`,text_enforced:o.prev.enforced,title:"Previous site",path:"previous",additionalClass:"prev-btn"},random:{symbol:r(23,23),text:`${r(20,20,"margin-right: 4px; margin-top: 1px;")} ${o.random.default}`,text_enforced:o.random.enforced,title:"Random site",path:"random",additionalClass:"random-btn"},next:{symbol:"\xbb",text:`${o.next.default} \xbb`,text_enforced:o.next.enforced,title:"Next site",path:"next",additionalClass:"next-btn"},logoOnly:{symbol:r(23,23),text:r(23,23),path:"",additionalClass:"logo-only"}}),l=Object.freeze({full:{showTitle:!0,actions:["prev","random","next"]},"no-text":{showTitle:!1,actions:["prev","random","next"]},"two-way":{showTitle:!1,actions:["prev","logoOnly","next"],showLogoInMiddle:!0},"one-way":{showTitle:!1,actions:["next"],showLogoInButton:!0},"random-only":{showTitle:!1,actions:["random"]}}),g=Object.freeze({reset:"\n .webring-nav,\n .webring-nav div,\n .webring-nav span,\n .webring-nav nav,\n .webring-nav a,\n .webring-nav div::before,\n .webring-nav span::before,\n .webring-nav nav::before,\n .webring-nav a::before,\n .webring-nav div::after,\n .webring-nav span::after,\n .webring-nav nav::after,\n .webring-nav a::after {\n all: initial;\n box-sizing: border-box;\n }\n\n // .webring-nav svg,\n // .webring-nav svg * {\n // all: revert;\n // fill: currentColor;\n // }\n\n .webring-nav,\n .webring-nav div,\n .webring-nav span,\n .webring-nav nav,\n .webring-nav a {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n color: inherit;\n }\n\n .webring-nav div,\n .webring-nav span,\n .webring-nav nav,\n .webring-nav a {\n display: initial;\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n text-decoration: none;\n color: inherit;\n font-weight: inherit;\n font-size: inherit;\n line-height: inherit;\n vertical-align: baseline;\n box-shadow: none;\n outline: none;\n transform: none;\n opacity: 1;\n visibility: visible;\n position: static;\n float: none;\n clear: none;\n overflow: visible;\n white-space: normal;\n text-align: left;\n letter-spacing: normal;\n word-spacing: normal;\n text-transform: none;\n text-shadow: none;\n list-style: none;\n border-radius: 0;\n min-width: auto;\n max-width: none;\n min-height: auto;\n max-height: none;\n width: auto;\n height: auto;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: auto;\n }\n\n .webring-nav a {\n cursor: pointer;\n }\n ",layout:'\n .webring-nav {\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;\n font-size: 16px;\n display: flex;\n flex-direction: column;\n align-items: center;\n max-width: 350px;\n margin: 0 auto;\n padding: 10px;\n box-sizing: border-box;\n }\n .webring-nav .webring-title {\n margin-bottom: 8px;\n margin-top: 0;\n padding: 0;\n font-size: inherit;\n line-height: normal;\n }\n .webring-nav nav {\n display: flex;\n gap: 10px;\n width: 100%;\n justify-content: center;\n align-items: center;\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n .webring-nav .webring-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px 12px;\n text-decoration: none;\n box-sizing: border-box;\n margin: 0;\n }\n .webring-nav .webring-btn.random-btn {\n padding: 6px 8px;\n }\n .webring-nav nav .logo-only {\n padding: 8px 3px 6px 3px;\n margin: 0;\n }\n .webring-nav[data-widget-type="no-text"] {\n padding: 8px 10px;\n }\n .webring-nav[data-widget-type="one-way"] {\n max-width: 200px;\n }\n .webring-nav .webring-logo-inline {\n display: inline-block;\n vertical-align: middle;\n margin-right: 6px;\n margin-top: 1px;\n margin-bottom: 0;\n margin-left: 0;\n }\n .webring-nav[data-button-text="false"] .prev-btn {\n padding-top: 5px;\n padding-right: 12.5px;\n }\n .webring-nav[data-button-text="false"] .next-btn {\n padding-top: 5px;\n padding-left: 12.5px;\n }\n ',design:'\n .webring-nav[data-widget-type="full"] {\n border: 2.5px solid #000000;\n }\n .webring-nav .webring-title {\n font-weight: 600;\n }\n .webring-nav .webring-btn {\n text-wrap: nowrap;\n color: #000000;\n font-weight: 600;\n background-color: #ffffff;\n border: 2.5px solid #000000;\n transition: background-color 0.2s ease, color 0.2s ease;\n }\n .webring-nav .webring-btn:hover {\n background-color: #000000;\n color: #ffffff;\n }\n .webring-nav .webring-btn:focus {\n outline: none;\n background-color: transparent;\n color: #000000;\n }\n .webring-nav .webring-btn:active {\n border-color: #000000;\n background-color: #000000;\n color: #ffffff;\n }\n '});let s=!1;n()}();
@@ -31,9 +31,9 @@ module Webring
31
31
  # PATCH/PUT /webring/members/1
32
32
  def update
33
33
  if member.update(member_params)
34
- redirect_to admin_panel_member_path(member), notice: 'Member was successfully updated.'
34
+ update_success_response
35
35
  else
36
- render :edit, status: :unprocessable_entity
36
+ update_error_response
37
37
  end
38
38
  end
39
39
 
@@ -46,6 +46,20 @@ module Webring
46
46
 
47
47
  private
48
48
 
49
+ def update_success_response
50
+ respond_to do |format|
51
+ format.html { redirect_to admin_panel_member_path(member), notice: 'Member was successfully updated.' }
52
+ format.json { head :ok }
53
+ end
54
+ end
55
+
56
+ def update_error_response
57
+ respond_to do |format|
58
+ format.html { render :edit, status: :unprocessable_entity }
59
+ format.json { render json: { status: 'error', errors: member.errors }, status: :unprocessable_entity }
60
+ end
61
+ end
62
+
49
63
  def members
50
64
  @members ||= Member.all.order(created_at: :desc)
51
65
  end
@@ -55,7 +69,7 @@ module Webring
55
69
  end
56
70
 
57
71
  def member_params
58
- params.require(:member).permit(:name, :url, :description)
72
+ params.require(:member).permit(:name, :url, :description, :status)
59
73
  end
60
74
  end
61
75
  end
@@ -35,7 +35,7 @@ module Webring
35
35
  end
36
36
 
37
37
  def find_member
38
- @member = Webring::Member.find_by(uid: permitted_params[:source_member_uid])
38
+ @member = Webring::Member.active.find_by(uid: permitted_params[:source_member_uid])
39
39
  return if @member
40
40
 
41
41
  render_member_not_found
@@ -43,13 +43,13 @@ module Webring
43
43
 
44
44
  def check_member_exists
45
45
  member_uid = permitted_params[:source_member_uid]
46
- return unless member_uid.present? && !Webring::Member.exists?(uid: member_uid)
46
+ return unless member_uid.present? && !Webring::Member.active.exists?(uid: member_uid)
47
47
 
48
48
  render_member_not_found
49
49
  end
50
50
 
51
51
  def ensure_members_exist
52
- return if Webring::Member.exists?
52
+ return if Webring::Member.active.exists?
53
53
 
54
54
  render plain: 'No members in the webring', status: :not_found
55
55
  end
@@ -4,55 +4,57 @@ module Webring
4
4
  # Find the next member in the webring after the current one
5
5
  # If current member is the last, return the first member (ring concept)
6
6
  def find_next(source_member_uid)
7
- source_member = find_by(uid: source_member_uid)
8
- return first_member_by_creation unless source_member
7
+ source_member = active.find_by(uid: source_member_uid)
8
+ return first_active_member_by_creation unless source_member
9
9
 
10
- find_next_member(source_member) || first_member_by_creation
10
+ find_next_active_member(source_member) || first_active_member_by_creation
11
11
  end
12
12
 
13
13
  # Find the previous member in the webring before the current one
14
14
  # If current member is the first, return the last member (ring concept)
15
15
  def find_previous(source_member_uid)
16
- source_member = find_by(uid: source_member_uid)
17
- return last_member_by_creation unless source_member
16
+ source_member = active.find_by(uid: source_member_uid)
17
+ return last_active_member_by_creation unless source_member
18
18
 
19
- find_previous_member(source_member) || last_member_by_creation
19
+ find_previous_active_member(source_member) || last_active_member_by_creation
20
20
  end
21
21
 
22
22
  # Find a random member, excluding the current one if provided
23
23
  # If current member is the only one, return it
24
24
  def find_random(source_member_uid: nil)
25
- return order('RANDOM()').first if source_member_uid.blank?
25
+ return active.order('RANDOM()').first if source_member_uid.blank?
26
26
 
27
27
  # Use exists? check to avoid loading records when not needed
28
- excluded_scope = where.not(uid: source_member_uid)
28
+ excluded_scope = active.where.not(uid: source_member_uid)
29
29
 
30
30
  if excluded_scope.exists?
31
31
  excluded_scope.order('RANDOM()').first
32
32
  else
33
- # if only one member exists (the current one), return it
34
- find_by(uid: source_member_uid)
33
+ # if only one active member exists (the current one), return it
34
+ active.find_by(uid: source_member_uid)
35
35
  end
36
36
  end
37
37
 
38
38
  private
39
39
 
40
- def first_member_by_creation
41
- order(created_at: :asc).first
40
+ def first_active_member_by_creation
41
+ active.order(created_at: :asc).first
42
42
  end
43
43
 
44
- def last_member_by_creation
45
- order(created_at: :desc).first
44
+ def last_active_member_by_creation
45
+ active.order(created_at: :desc).first
46
46
  end
47
47
 
48
- def find_next_member(source_member)
49
- where('created_at > ?', source_member.created_at)
48
+ def find_next_active_member(source_member)
49
+ active
50
+ .where('created_at > ?', source_member.created_at)
50
51
  .order(created_at: :asc)
51
52
  .first
52
53
  end
53
54
 
54
- def find_previous_member(source_member)
55
- where('created_at < ?', source_member.created_at)
55
+ def find_previous_active_member(source_member)
56
+ active
57
+ .where('created_at < ?', source_member.created_at)
56
58
  .order(created_at: :desc)
57
59
  .first
58
60
  end
@@ -4,6 +4,9 @@ module Webring
4
4
 
5
5
  UID_LENGTH = 16 # 32-character hex string
6
6
 
7
+ # :active?, :disabled? -- :active!, :disabled!
8
+ enum :status, { active: 0, disabled: 1 }
9
+
7
10
  self.filter_attributes += %i[uid]
8
11
 
9
12
  validates :url, presence: true, uniqueness: true
@@ -5,6 +5,7 @@ class CreateWebringMembers < ActiveRecord::Migration<%= "[#{Rails::VERSION::MAJO
5
5
  t.string :name, null: false
6
6
  t.string :url, null: false
7
7
  t.text :description, null: false
8
+ t.integer :status, null: false, default: 0
8
9
 
9
10
  t.index :uid, unique: true
10
11
  t.index :name, unique: true
@@ -4,6 +4,9 @@ module Webring
4
4
 
5
5
  UID_LENGTH = 16 # 32-character hex string
6
6
 
7
+ # :active?, :disabled? -- :active!, :disabled!
8
+ enum :status, { active: 0, disabled: 1 }
9
+
7
10
  self.filter_attributes += %i[uid]
8
11
 
9
12
  validates :url, presence: true, uniqueness: true
@@ -35,7 +35,7 @@ module Webring
35
35
  end
36
36
 
37
37
  def find_member
38
- @member = Webring::Member.find_by(uid: permitted_params[:source_member_uid])
38
+ @member = Webring::Member.active.find_by(uid: permitted_params[:source_member_uid])
39
39
  return if @member
40
40
 
41
41
  render_member_not_found
@@ -43,13 +43,13 @@ module Webring
43
43
 
44
44
  def check_member_exists
45
45
  member_uid = permitted_params[:source_member_uid]
46
- return unless member_uid.present? && !Webring::Member.exists?(uid: member_uid)
46
+ return unless member_uid.present? && !Webring::Member.active.exists?(uid: member_uid)
47
47
 
48
48
  render_member_not_found
49
49
  end
50
50
 
51
51
  def ensure_members_exist
52
- return if Webring::Member.exists?
52
+ return if Webring::Member.active.exists?
53
53
 
54
54
  render plain: 'No members in the webring', status: :not_found
55
55
  end
@@ -57,5 +57,12 @@ module Webring
57
57
  def render_member_not_found
58
58
  render plain: 'Member not found', status: :not_found
59
59
  end
60
+
61
+ def set_cors_headers
62
+ headers['Access-Control-Allow-Origin'] = '*'
63
+ headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
64
+ headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
65
+ headers['Access-Control-Max-Age'] = '86400'
66
+ end
60
67
  end
61
68
  end
@@ -1,3 +1,3 @@
1
1
  module Webring
2
- VERSION = '1.4.3'.freeze
2
+ VERSION = '1.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webring-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shkoda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-10 00:00:00.000000000 Z
11
+ date: 2025-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails