webring-rails 1.6.0 → 1.7.2

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: 82bc3c0e725233f97c81c7f5d93300155cf4a926618b9f0cfc0b34728411ce90
4
- data.tar.gz: 81704a8acd70cf5f060f6208eed0512ace47504e28ddf4071caee9d04e7f4589
3
+ metadata.gz: a98865565d0e12327382922de903a721178b48400b20c7c0a1cf20b1f278de74
4
+ data.tar.gz: 8d707539b2a0e8191efd0394810163b984bf38aa2e1a5016d75bf0891d3d2322
5
5
  SHA512:
6
- metadata.gz: b83576e412c50d3e060bdfc056d2695da79f576aae7c398d85e4a0a8efe77c68d3dd57bdcef5cdbb5c1654dc7e7331f4894817cf05b0c6c853060bd36fcab269
7
- data.tar.gz: 1a717972d57d3361d51d6f250b1ada90ea38d7d5142dba6bbf573ab6fd57a39d9f5431dd835f2ede7be9969f166805f1fd8d1541620254e2e4eaffa6c2cb96ba
6
+ metadata.gz: f367e6a0b4fdf72458064c51a6fa38103717e849ad0f623ede4224dc3b0c22662a2edaab102a6bbacfe562b5b597019851dc88834936fe02ed9007b4440a03c5
7
+ data.tar.gz: 138a86db76bd06d4960fe039c121f27bcd52fc7574bfbc325104a920382c78c3a8b73c8701786a4abc73d8cf2f3f9424fe58d8885d3379259a1620c5fd5f1872
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ![Webring Widget Sample](widget-sample.png)
2
2
 
3
- # Webring for Rails
3
+ # Webring for Rails [![Gem Version](https://badge.fury.io/rb/webring-rails.svg)](https://badge.fury.io/rb/webring-rails)
4
4
 
5
5
  [Webring for Rails (webring-rails)](https://github.com/cybergizer-hq/webring-rails) is a flexible engine for creating and managing a webring system in your Ruby on Rails application. A webring is a collection of websites linked together in a circular structure, allowing visitors to navigate from one site to another.
6
6
 
@@ -303,7 +303,7 @@
303
303
  fill: currentColor;
304
304
  }
305
305
 
306
- /* Light theme defaults - these have lower specificity than member's rules */
306
+ /* Light theme defaults */
307
307
  .webring-nav {
308
308
  --webring-theme-bg: #ffffff;
309
309
  --webring-theme-border: #000000;
@@ -394,13 +394,13 @@
394
394
  wrapperDiv.setAttribute('data-theme', theme);
395
395
 
396
396
  // Apply custom texts efficiently
397
- const customTexts = {
397
+ const customizedConfigs = {
398
398
  prev: NAVIGATION_ACTIONS.prev.text_enforced
399
399
  ? NAVIGATION_ACTIONS.prev
400
400
  : (prevText ? {...NAVIGATION_ACTIONS.prev, text: `« ${prevText}`} : NAVIGATION_ACTIONS.prev),
401
401
  random: NAVIGATION_ACTIONS.random.text_enforced
402
402
  ? NAVIGATION_ACTIONS.random
403
- : (randomText ? {...NAVIGATION_ACTIONS.random, text: `${logoSvg(20, 20, "margin-right: 4px; margin-top: 1px;")} ${randomText}`} : NAVIGATION_ACTIONS.random),
403
+ : (randomText && randomText.trim() !== '' ? {...NAVIGATION_ACTIONS.random, text: `${logoSvg(20, 20, "margin-right: 4px; margin-top: 1px;")} ${randomText}`} : NAVIGATION_ACTIONS.random),
404
404
  next: NAVIGATION_ACTIONS.next.text_enforced
405
405
  ? NAVIGATION_ACTIONS.next
406
406
  : (nextText ? {...NAVIGATION_ACTIONS.next, text: `${nextText} »`} : NAVIGATION_ACTIONS.next),
@@ -424,7 +424,7 @@
424
424
 
425
425
  // Create buttons
426
426
  config.actions.forEach(action => {
427
- const actionConfig = customTexts[action];
427
+ const actionConfig = customizedConfigs[action];
428
428
 
429
429
  // Logo-only block
430
430
  if (action === 'logoOnly') {
@@ -444,13 +444,18 @@
444
444
  if (widgetType === 'one-way' && config.showLogoInButton && action === 'next') {
445
445
  const buttonTextContent = NAVIGATION_ACTIONS.next.text_enforced ?
446
446
  FULL_TEXT_DEFAULTS.next.default :
447
- (nextText || customTexts.next.text.replace(' »', ''));
447
+ (nextText || customizedConfigs.next.text.replace(' »', ''));
448
448
 
449
449
  linkElem.innerHTML = buttonText
450
450
  ? `<span class="webring-logo-inline">${logoSvg(20, 20)}</span> ${buttonTextContent} »`
451
451
  : `<span class="webring-logo-inline">${logoSvg(20, 20)}</span> ${actionConfig.symbol}`;
452
452
  } else {
453
- linkElem.innerHTML = buttonText ? actionConfig.text : actionConfig.symbol;
453
+ // Special case: if buttonText is true but randomText is empty, use symbol for random button
454
+ if (action === 'random' && buttonText && (randomText?.trim() === '' || randomText?.trim() === undefined)) {
455
+ linkElem.innerHTML = logoSvg(23, 23, "margin-top: 1px;"); // buttons with text are 1px taller
456
+ } else {
457
+ linkElem.innerHTML = buttonText ? actionConfig.text : actionConfig.symbol;
458
+ }
454
459
  }
455
460
 
456
461
  navElem.appendChild(linkElem);
@@ -1 +1 @@
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.insertBefore(t,document.head.firstChild)),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 r=n||document.currentScript||document.getElementsByTagName("script")[document.getElementsByTagName("script").length-1];if(!r)return;const i=r.getAttribute("data-member-uid"),s=r.getAttribute("data-widget-type")??e.DEFAULT_TYPE,c=r.getAttribute("data-target-id")??e.DEFAULT_TARGET_ID,w="false"!==r.getAttribute("data-button-text"),f=r.getAttribute("data-styles")??e.DEFAULT_STYLE_TYPE,m=e.VALID_STYLE_TYPES.includes(f)?f:e.DEFAULT_STYLE_TYPE,v=r.getAttribute("data-theme")??e.DEFAULT_THEME,x=e.VALID_THEMES.includes(v)?v:e.DEFAULT_THEME,p=r.getAttribute("data-prev-text"),u=r.getAttribute("data-random-text"),h=r.getAttribute("data-next-text"),E=r.getAttribute("data-widget-text");if(!i)return void console.error("Webring Widget: Missing data-member-uid attribute on script tag.");if(!e.VALID_TYPES.includes(s))return void console.error(`Webring Widget: Invalid widget type "${s}". Valid types: ${e.VALID_TYPES.join(", ")}`);const y=r.getAttribute("src"),T=new URL(y,window.location.href).origin,_=function(){const n=document.getElementById(c);if(!n)return void console.error(`Webring Widget: No element with id "${c}" found.`);l||(t(m),l=!0);const e=document.createDocumentFragment(),r=document.createElement("div");r.className="webring-nav",r.setAttribute("data-widget-type",s),r.setAttribute("data-button-text",w.toString()),r.setAttribute("data-theme",x);const g={prev:b.prev.text_enforced?b.prev:p?{...b.prev,text:`\xab ${p}`}:b.prev,random:b.random.text_enforced?b.random:u?{...b.random,text:`${o(20,20,"margin-right: 4px; margin-top: 1px;")} ${u}`}:b.random,next:b.next.text_enforced?b.next:h?{...b.next,text:`${h} \xbb`}:b.next,logoOnly:b.logoOnly},f=d[s];if(f.showTitle){const n=document.createElement("span");n.className="webring-title",n.innerHTML=a.widgetTitle.enforced?a.widgetTitle.default:E??a.widgetTitle.default,r.appendChild(n)}const v=document.createElement("nav");v.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 v.appendChild(n)}const t=document.createElement("a");if(t.href=`${T}/webring/${e.path}?source_member_uid=${i}`,t.title=e.title,t.className=`webring-btn ${e.additionalClass}`,"one-way"===s&&f.showLogoInButton&&"next"===n){const n=b.next.text_enforced?a.next.default:h||g.next.text.replace(" \xbb","");t.innerHTML=w?`<span class="webring-logo-inline">${o(20,20)}</span> ${n} \xbb`:`<span class="webring-logo-inline">${o(20,20)}</span> ${e.symbol}`}else t.innerHTML=w?e.text:e.symbol;v.appendChild(t)})),r.appendChild(v),e.appendChild(r),n.innerHTML="",n.appendChild(e)};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",_):_()}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",VALID_THEMES:Object.freeze(["light","dark"]),DEFAULT_THEME:"light"}),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}}),r="<<REPLACE_ME_TEXT_DEFAULTS>>",i="<<REPLACE_ME_TEXT_DEFAULTS>>"!==r?"string"==typeof r?JSON.parse(r):r:{},a=Object.freeze(Object.keys(t).reduce(((n,e)=>{const r=i[e];return n[e]={default:r?.default??t[e].default,enforced:r?.enforced??t[e].enforced},n}),{})),o="<<REPLACE_ME_LOGO_SVG_FUNCTION>>",b=Object.freeze({prev:{symbol:"\xab",text:`\xab ${a.prev.default}`,text_enforced:a.prev.enforced,title:"Previous site",path:"previous",additionalClass:"prev-btn"},random:{symbol:o(23,23),text:`${o(20,20,"margin-right: 4px; margin-top: 1px;")} ${a.random.default}`,text_enforced:a.random.enforced,title:"Random site",path:"random",additionalClass:"random-btn"},next:{symbol:"\xbb",text:`${a.next.default} \xbb`,text_enforced:a.next.enforced,title:"Next site",path:"next",additionalClass:"next-btn"},logoOnly:{symbol:o(23,23),text:o(23,23),path:"",additionalClass:"logo-only"}}),d=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,\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: 0 0 8px 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: 1px 6px 0 0;\n }\n .webring-nav[data-button-text="false"] .prev-btn {\n padding: 5px 12.5px 6px 12px;\n }\n .webring-nav[data-button-text="false"] .next-btn {\n padding: 5px 12px 6px 12.5px;\n }\n ',design:'\n /* CSS Custom Properties for easy theming */\n .webring-nav {\n /* Internal variables that use public API with fallbacks */\n --webring-bg-color: var(--webring-theme-bg);\n --webring-border-color: var(--webring-theme-border);\n --webring-text-color: var(--webring-theme-text);\n --webring-btn-bg: var(--webring-theme-btn-bg);\n --webring-btn-border: var(--webring-theme-btn-border);\n --webring-btn-text: var(--webring-theme-btn-text);\n --webring-btn-hover-bg: var(--webring-theme-btn-hover-bg);\n --webring-btn-hover-text: var(--webring-theme-btn-hover-text);\n }\n\n /* Common theme styles using CSS variables */\n .webring-nav {\n background-color: var(--webring-bg-color);\n }\n .webring-nav[data-widget-type="full"] {\n border: 2.5px solid var(--webring-border-color);\n }\n .webring-nav .webring-title {\n font-weight: 600;\n color: var(--webring-text-color);\n }\n .webring-nav .webring-btn {\n text-wrap: nowrap;\n font-weight: 600;\n color: var(--webring-btn-text);\n background-color: var(--webring-btn-bg);\n border: 2.5px solid var(--webring-btn-border);\n transition: background-color 0.2s ease, color 0.2s ease;\n }\n .webring-nav .webring-btn:focus {\n outline: none;\n background-color: transparent;\n color: var(--webring-btn-text);\n }\n .webring-nav .webring-btn:hover,\n .webring-nav .webring-btn:active {\n background-color: var(--webring-btn-hover-bg);\n color: var(--webring-btn-hover-text);\n }\n .webring-nav svg {\n fill: currentColor;\n }\n\n /* Light theme defaults - these have lower specificity than member\'s rules */\n .webring-nav {\n --webring-theme-bg: #ffffff;\n --webring-theme-border: #000000;\n --webring-theme-text: #000000;\n --webring-theme-btn-bg: #ffffff;\n --webring-theme-btn-border: #000000;\n --webring-theme-btn-text: #000000;\n --webring-theme-btn-hover-bg: #000000;\n --webring-theme-btn-hover-text: #ffffff;\n }\n\n /* Dark theme overrides */\n .webring-nav[data-theme="dark"] {\n --webring-theme-bg: #000000;\n --webring-theme-border: #ffffff;\n --webring-theme-text: #ffffff;\n --webring-theme-btn-bg: #000000;\n --webring-theme-btn-border: #ffffff;\n --webring-theme-btn-text: #ffffff;\n --webring-theme-btn-hover-bg: #ffffff;\n --webring-theme-btn-hover-text: #000000;\n }\n '});let l=!1;n()}();
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.insertBefore(t,document.head.firstChild)),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 r=n||document.currentScript||document.getElementsByTagName("script")[document.getElementsByTagName("script").length-1];if(!r)return;const i=r.getAttribute("data-member-uid"),s=r.getAttribute("data-widget-type")??e.DEFAULT_TYPE,w=r.getAttribute("data-target-id")??e.DEFAULT_TARGET_ID,c="false"!==r.getAttribute("data-button-text"),f=r.getAttribute("data-styles")??e.DEFAULT_STYLE_TYPE,m=e.VALID_STYLE_TYPES.includes(f)?f:e.DEFAULT_STYLE_TYPE,v=r.getAttribute("data-theme")??e.DEFAULT_THEME,x=e.VALID_THEMES.includes(v)?v:e.DEFAULT_THEME,p=r.getAttribute("data-prev-text"),u=r.getAttribute("data-random-text"),h=r.getAttribute("data-next-text"),E=r.getAttribute("data-widget-text");if(!i)return void console.error("Webring Widget: Missing data-member-uid attribute on script tag.");if(!e.VALID_TYPES.includes(s))return void console.error(`Webring Widget: Invalid widget type "${s}". Valid types: ${e.VALID_TYPES.join(", ")}`);const T=r.getAttribute("src"),y=new URL(T,window.location.href).origin,_=function(){const n=document.getElementById(w);if(!n)return void console.error(`Webring Widget: No element with id "${w}" found.`);l||(t(m),l=!0);const e=document.createDocumentFragment(),r=document.createElement("div");r.className="webring-nav",r.setAttribute("data-widget-type",s),r.setAttribute("data-button-text",c.toString()),r.setAttribute("data-theme",x);const g={prev:b.prev.text_enforced?b.prev:p?{...b.prev,text:`\xab ${p}`}:b.prev,random:b.random.text_enforced?b.random:u&&""!==u.trim()?{...b.random,text:`${o(20,20,"margin-right: 4px; margin-top: 1px;")} ${u}`}:b.random,next:b.next.text_enforced?b.next:h?{...b.next,text:`${h} \xbb`}:b.next,logoOnly:b.logoOnly},f=d[s];if(f.showTitle){const n=document.createElement("span");n.className="webring-title",n.innerHTML=a.widgetTitle.enforced?a.widgetTitle.default:E??a.widgetTitle.default,r.appendChild(n)}const v=document.createElement("nav");v.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 v.appendChild(n)}const t=document.createElement("a");if(t.href=`${y}/webring/${e.path}?source_member_uid=${i}`,t.title=e.title,t.className=`webring-btn ${e.additionalClass}`,"one-way"===s&&f.showLogoInButton&&"next"===n){const n=b.next.text_enforced?a.next.default:h||g.next.text.replace(" \xbb","");t.innerHTML=c?`<span class="webring-logo-inline">${o(20,20)}</span> ${n} \xbb`:`<span class="webring-logo-inline">${o(20,20)}</span> ${e.symbol}`}else"random"!==n||!c||""!==u?.trim()&&void 0!==u?.trim()?t.innerHTML=c?e.text:e.symbol:t.innerHTML=o(23,23,"margin-top: 1px;");v.appendChild(t)})),r.appendChild(v),e.appendChild(r),n.innerHTML="",n.appendChild(e)};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",_):_()}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",VALID_THEMES:Object.freeze(["light","dark"]),DEFAULT_THEME:"light"}),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}}),r="<<REPLACE_ME_TEXT_DEFAULTS>>",i="<<REPLACE_ME_TEXT_DEFAULTS>>"!==r?"string"==typeof r?JSON.parse(r):r:{},a=Object.freeze(Object.keys(t).reduce(((n,e)=>{const r=i[e];return n[e]={default:r?.default??t[e].default,enforced:r?.enforced??t[e].enforced},n}),{})),o="<<REPLACE_ME_LOGO_SVG_FUNCTION>>",b=Object.freeze({prev:{symbol:"\xab",text:`\xab ${a.prev.default}`,text_enforced:a.prev.enforced,title:"Previous site",path:"previous",additionalClass:"prev-btn"},random:{symbol:o(23,23),text:`${o(20,20,"margin-right: 4px; margin-top: 1px;")} ${a.random.default}`,text_enforced:a.random.enforced,title:"Random site",path:"random",additionalClass:"random-btn"},next:{symbol:"\xbb",text:`${a.next.default} \xbb`,text_enforced:a.next.enforced,title:"Next site",path:"next",additionalClass:"next-btn"},logoOnly:{symbol:o(23,23),text:o(23,23),path:"",additionalClass:"logo-only"}}),d=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,\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: 0 0 8px 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: 1px 6px 0 0;\n }\n .webring-nav[data-button-text="false"] .prev-btn {\n padding: 5px 12.5px 6px 12px;\n }\n .webring-nav[data-button-text="false"] .next-btn {\n padding: 5px 12px 6px 12.5px;\n }\n ',design:'\n /* CSS Custom Properties for easy theming */\n .webring-nav {\n /* Internal variables that use public API with fallbacks */\n --webring-bg-color: var(--webring-theme-bg);\n --webring-border-color: var(--webring-theme-border);\n --webring-text-color: var(--webring-theme-text);\n --webring-btn-bg: var(--webring-theme-btn-bg);\n --webring-btn-border: var(--webring-theme-btn-border);\n --webring-btn-text: var(--webring-theme-btn-text);\n --webring-btn-hover-bg: var(--webring-theme-btn-hover-bg);\n --webring-btn-hover-text: var(--webring-theme-btn-hover-text);\n }\n\n /* Common theme styles using CSS variables */\n .webring-nav {\n background-color: var(--webring-bg-color);\n }\n .webring-nav[data-widget-type="full"] {\n border: 2.5px solid var(--webring-border-color);\n }\n .webring-nav .webring-title {\n font-weight: 600;\n color: var(--webring-text-color);\n }\n .webring-nav .webring-btn {\n text-wrap: nowrap;\n font-weight: 600;\n color: var(--webring-btn-text);\n background-color: var(--webring-btn-bg);\n border: 2.5px solid var(--webring-btn-border);\n transition: background-color 0.2s ease, color 0.2s ease;\n }\n .webring-nav .webring-btn:focus {\n outline: none;\n background-color: transparent;\n color: var(--webring-btn-text);\n }\n .webring-nav .webring-btn:hover,\n .webring-nav .webring-btn:active {\n background-color: var(--webring-btn-hover-bg);\n color: var(--webring-btn-hover-text);\n }\n .webring-nav svg {\n fill: currentColor;\n }\n\n /* Light theme defaults */\n .webring-nav {\n --webring-theme-bg: #ffffff;\n --webring-theme-border: #000000;\n --webring-theme-text: #000000;\n --webring-theme-btn-bg: #ffffff;\n --webring-theme-btn-border: #000000;\n --webring-theme-btn-text: #000000;\n --webring-theme-btn-hover-bg: #000000;\n --webring-theme-btn-hover-text: #ffffff;\n }\n\n /* Dark theme overrides */\n .webring-nav[data-theme="dark"] {\n --webring-theme-bg: #000000;\n --webring-theme-border: #ffffff;\n --webring-theme-text: #ffffff;\n --webring-theme-btn-bg: #000000;\n --webring-theme-btn-border: #ffffff;\n --webring-theme-btn-text: #ffffff;\n --webring-theme-btn-hover-bg: #ffffff;\n --webring-theme-btn-hover-text: #000000;\n }\n '});let l=!1;n()}();
@@ -69,7 +69,7 @@ module Webring
69
69
  end
70
70
 
71
71
  def member_params
72
- params.require(:member).permit(:name, :url, :description, :status)
72
+ params.require(:member).permit(:name, :url, :owner_email, :description, :status)
73
73
  end
74
74
  end
75
75
  end
@@ -1,5 +1,7 @@
1
1
  module Webring
2
2
  class NavigationController < ApplicationController
3
+ before_action :set_cors_headers
4
+
3
5
  before_action :find_member, only: %i[next previous]
4
6
  before_action :ensure_members_exist, :check_member_exists, only: [:random]
5
7
 
@@ -3,7 +3,6 @@ module Webring
3
3
  # Disable CSRF protection for widget.js as it needs to be loaded from other domains
4
4
  skip_forgery_protection
5
5
 
6
- # Set CORS headers for the widget
7
6
  before_action :set_cors_headers
8
7
 
9
8
  # Serve the webring navigation widget JavaScript
@@ -28,13 +27,6 @@ module Webring
28
27
 
29
28
  private
30
29
 
31
- def set_cors_headers
32
- response.headers['Access-Control-Allow-Origin'] = '*'
33
- response.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
34
- response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
35
- response.headers['Access-Control-Max-Age'] = '86400'
36
- end
37
-
38
30
  # This function is used to generate the logo SVG function for the compiled widget.js file to overcome args names compression issue
39
31
  def logo_svg_function
40
32
  <<~JS
@@ -57,5 +49,12 @@ module Webring
57
49
  widgetTitle: { default: 'Webring', enforced: false }
58
50
  }
59
51
  end
52
+
53
+ def set_cors_headers
54
+ response.headers['Access-Control-Allow-Origin'] = '*'
55
+ response.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
56
+ response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
57
+ response.headers['Access-Control-Max-Age'] = '86400'
58
+ end
60
59
  end
61
60
  end
@@ -11,6 +11,7 @@ module Webring
11
11
  Webring::Member.create!(
12
12
  name: name,
13
13
  url: url,
14
+ owner_email: callback_email,
14
15
  description: description,
15
16
  webring_membership_request_id: id
16
17
  )
@@ -4,7 +4,8 @@ class CreateWebringMembers < ActiveRecord::Migration<%= "[#{Rails::VERSION::MAJO
4
4
  t.string :uid, null: false, limit: 32
5
5
  t.string :name, null: false
6
6
  t.string :url, null: false
7
- t.text :description, null: false
7
+ t.string :owner_email
8
+ t.text :description
8
9
  t.integer :status, null: false, default: 0
9
10
 
10
11
  t.index :uid, unique: true
@@ -1,5 +1,7 @@
1
1
  module Webring
2
2
  class NavigationController < ApplicationController
3
+ before_action :set_cors_headers
4
+
3
5
  before_action :find_member, only: %i[next previous]
4
6
  before_action :ensure_members_exist, :check_member_exists, only: [:random]
5
7
 
@@ -1,3 +1,3 @@
1
1
  module Webring
2
- VERSION = '1.6.0'.freeze
2
+ VERSION = '1.7.2'.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.6.0
4
+ version: 1.7.2
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-12 00:00:00.000000000 Z
11
+ date: 2025-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails