fictioneer/js/chapter.min.js
2024-12-30 06:11:00 +01:00

1 line
14 KiB
JavaScript

application.register("fictioneer-chapter",class extends Stimulus.Controller{static get targets(){return["bookmarkScroll","contentWrapper","index","content"]}static values={chapterId:Number,storyId:Number};startClick=0;lastToolsParagraph=null;tools=_$$$("paragraph-tools");progressBar=_$(".progress__bar");hasPassword=!!_$("article._password");checkmarkUpdated=!1;checkboxProgressBar=_$$$("site-setting-chapter-progress-bar");checkboxMinimalist=_$$$("site-setting-minimal");initialize(){this.progressBar&&this.hasContentTarget&&!this.hasPassword&&(this.trackProgress(),window.addEventListener("scroll.rAF",FcnUtils.throttle(this.trackProgress.bind(this),1e3/48)))}connect(){window.FictioneerApp.Controllers.fictioneerChapter=this,this.hasIndexTarget&&this.indexTargets.forEach((t=>{t.querySelector(`[data-id="${this.chapterIdValue}"]`)?.classList.add("current")}))}clickOutside({detail:{target:t}}){this.lastToolsParagraph&&!t.closest(".selected-paragraph")&&this.closeTools()}scrollToBookmark(){const t=window.FictioneerApp.Controllers.fictioneerBookmarks;if(!t)return void fcn_showNotification("Error: Bookmarks Controller not connected.",3,"warning");const e=t.data()?.[`ch-${this.chapterIdValue}`]?.["paragraph-id"];if(!e)return;const n=_$(`[data-paragraph-id="${e}"]`);n?.scrollIntoView({behavior:"smooth"})}openFullscreen(){document.documentElement.requestFullscreen?document.documentElement.requestFullscreen():document.documentElement.webkitRequestFullscreen&&document.documentElement.webkitRequestFullscreen()}closeFullscreen(){document.exitFullscreen?document.exitFullscreen():document.webkitExitFullscreen&&document.webkitExitFullscreen()}toggleTools(t){this.lastToolsParagraph?.classList.remove("selected-paragraph"),this.lastToolsParagraph!==t?(this.lastToolsParagraph=t,t.classList.add("selected-paragraph"),t.append(this.tools)):this.closeTools()}closeTools(){this.lastToolsParagraph?.classList.remove("selected-paragraph"),this.lastToolsParagraph=null}fastClick(t){""==window.getSelection().toString()&&(this.startClick=Date.now(),document.addEventListener("mouseup",(()=>{Date.now()<this.startClick+400&&this.#t(t.target)&&this.tools&&this.toggleTools(t.target.closest("p"))}),{once:!0}))}quote(t){const e=t.target.closest("p[data-paragraph-id]");if(!e)return;const n=window.getSelection()?window.getSelection().toString().trim():"",s=`[anchor]${e.id}[/anchor]`;let a=FcnUtils.extractTextNodes(e);if(a.length>16&&n.replace(/\s/g,"").length){const t=Math.ceil(.25*n.length);let e=fictioneer_tl.partial.quoteFragmentPrefix,s=fictioneer_tl.partial.quoteFragmentSuffix;n.startsWith(a.substring(0,t+1))&&(e=""),n.endsWith(a.substring(a.length-t,a.length))&&(s=""),a=`${e}${n}${s}`}fcn_showNotification(fictioneer_tl.notification.quoteAppendedToComment),FcnUtils.appendToComment(`\n[quote]${a} ${s}[/quote]\n`)}toggleBookmark({target:t}){const e=window.FictioneerApp.Controllers.fictioneerBookmarks;e?(e.toggle(t.closest("p[data-paragraph-id]").dataset.paragraphId,t.closest("[data-color]")?.dataset.color??"none"),window.matchMedia("(min-width: 1024px)").matches&&this.closeTools()):fcn_showNotification("Error: Bookmarks Controller not connected.",3,"warning")}copyLink(t){const e=t.target.closest("p[data-paragraph-id]");e&&FcnUtils.copyToClipboard(`${location.protocol}//${location.host}${location.pathname}#${e.id}`,fictioneer_tl.notification.linkCopiedToClipboard)}toggleIndexOrder({currentTarget:t}){const e=t.closest(".chapter-index");e.dataset.order="asc"===e.dataset.order?"desc":"asc"}trackProgress(){if(!this.progressBar||!this.hasContentTarget||this.hasPassword||this.checkboxMinimalist.checked||!(this.checkboxProgressBar?.checked??1))return;const t=this.contentTarget.getBoundingClientRect(),e=t.height,n=e-t.bottom-Math.max(t.top,0)+window.innerHeight;let s=100*n/e;if(document.body.classList.toggle("hasProgressBar",!(s<0||n>e+500)),s=FcnUtils.clamp(0,100,s),this.progressBar.style.width=`${s}%`,!this.checkmarkUpdated&&this.hasStoryIdValue&&this.storyIdValue&&s>=100&&FcnUtils.loggedIn()){if(this.checkmarkUpdated=!0,!this.hasChapterIdValue||!this.chapterIdValue||"function"!=typeof fcn_toggleCheckmark)return;fcn_toggleCheckmark(this.storyIdValue,this.chapterIdValue,!0)}}#t(t){return!(t.classList.contains("spoiler")||!t.closest("p[data-paragraph-id]")?.textContent.trim().length||!t.closest("p")?.parentElement?.classList.contains("chapter-formatting")||t.closest(".popup-menu-toggle, .skip-tools, .tts-interface, .paragraph-tools__actions, .hidden, .inside-epub, a, button, label, input, textarea, select, option"))}});const fcn_chapterKeyboardNavigation=t=>{if(["INPUT","TEXTAREA","SELECT","OPTION"].includes(t.target.tagName)||t.target.isContentEditable)return;const e={ArrowLeft:"a.button._navigation._prev",ArrowRight:"a.button._navigation._next"};if(!e[t.code])return;const n=_$(e[t.code]);n?.href&&(window.location.href=`${n.href}#start`)};if(document.addEventListener("keydown",fcn_chapterKeyboardNavigation),"#start"===window.location.hash){history.replaceState(null,document.title,window.location.pathname);const t=_$(".chapter__article");t&&FcnUtils.scrollTo(t,128)}const FcnFormatting={eFormattingTarget:_$(".chapter-formatting"),defaults:()=>({"font-saturation":0,"font-color":FcnGlobals.fontColors[0].css,"font-name":FcnGlobals.fonts[0].css,"font-size":100,"letter-spacing":0,"line-height":1.7,"paragraph-spacing":1.5,"site-width":document.documentElement.dataset.siteWidthDefault??"960",indent:!0,"show-sensitive-content":!0,"show-chapter-notes":!0,justify:!1,"show-comments":!0,"show-paragraph-tools":!0,timestamp:1664797604825,...FcnUtils.parseJSON(document.documentElement.dataset.defaultFormatting??"{}")}),get(){let t=FcnUtils.parseJSON(localStorage.getItem("fcnChapterFormatting"))??FcnFormatting.defaults();return Object.keys(t).length<15&&(t=FcnFormatting.defaults(),FcnFormatting.set(t)),t.timestamp<1651164557584&&(t=FcnFormatting.defaults(),t.timestamp=Date.now(),FcnFormatting.set(t)),t},set(t){"object"==typeof t&&localStorage.setItem("fcnChapterFormatting",JSON.stringify(t))}};function fcn_updateToggle(t,e,n,s={}){const a=FcnFormatting.get();s={save:!0,...s};const o=Boolean(t),i=_$(e);if(i&&(i.checked=o,i.closest("label").setAttribute("aria-checked",o)),s.toggleClass&&FcnFormatting.eFormattingTarget.classList.toggle(s.toggleClass,s.invertClass?!o:o),s.sensitiveContent){const t=_$$$("inline-sensitive-content-toggle");t?.classList.toggle("hide-sensitive",!o),t?.setAttribute("aria-checked",!o)}s.notes&&_$$(".chapter-note-hideable").forEach((t=>{t.classList.toggle("hidden",!o)})),s.comments&&_$$(".chapter-comments-hideable").forEach((t=>{t.classList.toggle("hidden",!o)})),a[n]=o,s.save&&FcnFormatting.set(a)}(()=>{"use strict";const t=_$$$("reader-settings-font-size-text"),e=_$$$("reader-settings-font-size-range"),n=_$$$("reader-settings-font-size-reset");if(!n)return;function s(s,a=!0){const o=FcnFormatting.get();s=FcnUtils.clamp(50,200,s??100),t.value=s,e.value=s,n.classList.toggle("_modified",100!=s),_$$(".resize-font").forEach((t=>{t.style.fontSize=`${s}%`})),o["font-size"]=s,a&&FcnFormatting.set(o)}function a(){s(this.value)}function o(){const t=FcnFormatting.get();s(parseFloat(t["font-size"])+parseFloat(this.dataset.modifier))}_$$$("reset-font")?.addEventListener("click",(()=>{s(100)})),n?.addEventListener("click",(()=>{s(100)})),e?.addEventListener("input",FcnUtils.throttle(a,1e3/24)),t?.addEventListener("input",a),_$$$("increase-font")?.addEventListener("click",o),_$$$("decrease-font")?.addEventListener("click",o);s(FcnFormatting.get()["font-size"],!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-font-color-reset"),e=_$$$("reader-settings-font-color-select");if(!t)return;function n(n,s=!0){const a=FcnFormatting.get();n=FcnUtils.clamp(0,FcnGlobals.fontColors.length-1,n),t.classList.toggle("_modified",n>0),e.value=n,FcnFormatting.eFormattingTarget.style.setProperty("--text-chapter",FcnGlobals.fontColors[n].css),a["font-color"]=FcnGlobals.fontColors[n].css,s&&FcnFormatting.set(a)}t.onclick=()=>{n(0)},e.onchange=t=>{n(t.target.value)},_$$(".font-color-stepper").forEach((t=>{t.addEventListener("click",(t=>{!function(t=1){let s=(e.selectedIndex+parseInt(t))%FcnGlobals.fontColors.length;s=s<0?FcnGlobals.fontColors.length-1:s,n(s)}(t.currentTarget.value)}))}));const s=FcnFormatting.get();n(FcnGlobals.fontColors.findIndex((t=>t.css==s["font-color"])),!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-font-reset"),e=_$$$("reader-settings-font-select");if(!t)return;function n(s,a=!0){const o=FcnFormatting.get();s=FcnUtils.clamp(0,FcnGlobals.fonts.length-1,s);let i=FcnGlobals.fonts[s].css;FcnGlobals.fonts[s].alt&&(i=`${i}, ${FcnGlobals.fonts[s].alt}`),s<0?n(0):(t.classList.toggle("_modified",s>0),e.value=s,_$$(".chapter-font-family").forEach((t=>{t.style.fontFamily=""===i?"var(--ff-system)":i+", var(--ff-system)"})),o["font-name"]=FcnGlobals.fonts[s].css,a&&FcnFormatting.set(o))}t.onclick=()=>{n(0)},e.onchange=t=>{n(t.target.value)},_$$(".font-stepper").forEach((t=>{t.addEventListener("click",(t=>{!function(t=1){let s=(e.selectedIndex+parseInt(t))%FcnGlobals.fonts.length;s=s<0?FcnGlobals.fonts.length-1:s,n(s)}(t.currentTarget.value)}))}));const s=FcnFormatting.get();n(FcnGlobals.fonts.findIndex((t=>t.css==s["font-name"])),!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-font-saturation-text"),e=_$$$("reader-settings-font-saturation-range"),n=_$$$("reader-settings-font-saturation-reset");if(!n)return;function s(s,a=!0){const o=FcnFormatting.get();s=FcnUtils.clamp(-1,1,s??0),t.value=parseInt(100*s),e.value=s,n.classList.toggle("_modified",0!=s),FcnFormatting.eFormattingTarget.style.setProperty("--font-saturation",`(${s>=0?1+s**2:1-s**2} + var(--font-saturation-offset))`),o["font-saturation"]=s,a&&FcnFormatting.set(o)}n?.addEventListener("click",(()=>{s(0)})),e?.addEventListener("input",FcnUtils.throttle((function(){s(this.value)}),1e3/24)),t?.addEventListener("input",(function(){s(parseInt(this.value)/100)}));s(FcnFormatting.get()["font-saturation"],!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-letter-spacing-text"),e=_$$$("reader-settings-letter-spacing-range"),n=_$$$("reader-settings-letter-spacing-reset"),s=FcnFormatting.defaults()["letter-spacing"];if(!n)return;function a(a,o=!0){const i=FcnFormatting.get();a=FcnUtils.clamp(-.1,.2,a??s),t.value=a,e.value=a,n.classList.toggle("_modified",a!=s),FcnFormatting.eFormattingTarget.style.letterSpacing=`calc(${a}em + var(--font-letter-spacing-base))`,i["letter-spacing"]=a,o&&FcnFormatting.set(i)}function o(){a(this.value)}n?.addEventListener("click",(()=>{a(s)})),e?.addEventListener("input",FcnUtils.throttle(o,1e3/24)),t?.addEventListener("input",o);a(FcnFormatting.get()["letter-spacing"],!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-paragraph-spacing-text"),e=_$$$("reader-settings-paragraph-spacing-range"),n=_$$$("reader-settings-paragraph-spacing-reset"),s=FcnFormatting.defaults()["paragraph-spacing"];if(!n)return;function a(a,o=!0){const i=FcnFormatting.get();a=FcnUtils.clamp(0,3,a??s),t.value=a,e.value=a,n.classList.toggle("_modified",a!=s),FcnFormatting.eFormattingTarget.style.setProperty("--paragraph-spacing",`${a}em`),i["paragraph-spacing"]=a,o&&FcnFormatting.set(i)}function o(){a(this.value)}n?.addEventListener("click",(()=>{a(s)})),e?.addEventListener("input",FcnUtils.throttle(o,1e3/24)),t?.addEventListener("input",o);a(FcnFormatting.get()["paragraph-spacing"],!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-line-height-text"),e=_$$$("reader-settings-line-height-range"),n=_$$$("reader-settings-line-height-reset"),s=FcnFormatting.defaults()["line-height"];if(!n)return;function a(a,o=!0){const i=FcnFormatting.get();a=FcnUtils.clamp(.8,3,a??s),t.value=a,e.value=a,n.classList.toggle("_modified",a!=s),FcnFormatting.eFormattingTarget.style.lineHeight=`${a}`,i["line-height"]=a,o&&FcnFormatting.set(i)}function o(){a(this.value)}n?.addEventListener("click",(()=>{a(s)})),e?.addEventListener("input",FcnUtils.throttle(o,1e3/24)),t?.addEventListener("input",o);a(FcnFormatting.get()["line-height"],!1)})(),(()=>{"use strict";const t=_$$$("reader-settings-site-width-text"),e=_$$$("reader-settings-site-width-range"),n=_$$$("reader-settings-site-width-reset"),s=FcnFormatting.defaults()["site-width"];if(!n)return;function a(a,o=!0){const i=FcnFormatting.get(),r=_$("main");a=FcnUtils.clamp(640,1920,a??s),t.value=a,e.value=a,n.classList.toggle("_modified",a!=s),r.style.setProperty("--site-width",`${a}px`),r.classList.toggle("_default-width",a==document.documentElement.dataset.siteWidthDefault),r.classList.toggle("_below-1024",a<1024&&a>=768),r.classList.toggle("_below-768",a<768&&a>640),r.classList.toggle("_640-and-below",a<=640),i["site-width"]=a,o&&FcnFormatting.set(i)}function o(){a(this.value)}n?.addEventListener("click",(()=>{a(s)})),e?.addEventListener("input",FcnUtils.throttle(o,1e3/24)),t?.addEventListener("input",o);a(FcnFormatting.get()["site-width"],!1)})(),_$$("#reader-settings-indent-toggle").forEach((t=>{const e={invertClass:!0,toggleClass:"no-indent"},n="indent";t.onclick=s=>{fcn_updateToggle(s.currentTarget.checked,`#${t.id}`,n,e)};fcn_updateToggle(FcnFormatting.get()[n],`#${t.id}`,n,{save:!1,...e})})),_$$("#reader-settings-justify-toggle").forEach((t=>{const e={toggleClass:"justify"},n="justify";t.onclick=s=>{fcn_updateToggle(s.currentTarget.checked,`#${t.id}`,n,e)};fcn_updateToggle(FcnFormatting.get()[n],`#${t.id}`,n,{save:!1,...e})})),_$$("#reader-settings-paragraph-tools-toggle").forEach((t=>{const e="show-paragraph-tools";t.onclick=n=>{fcn_updateToggle(n.currentTarget.checked,`#${t.id}`,e)};fcn_updateToggle(FcnFormatting.get()[e],`#${t.id}`,e,{save:!1})})),_$$("#reader-settings-chapter-notes-toggle").forEach((t=>{const e={notes:!0},n="show-chapter-notes";t.onclick=s=>{fcn_updateToggle(s.currentTarget.checked,`#${t.id}`,n,e)};fcn_updateToggle(FcnFormatting.get()[n],`#${t.id}`,n,{save:!1,...e})})),_$$("#reader-settings-comments-toggle").forEach((t=>{const e={comments:!0},n="show-comments";t.onclick=s=>{fcn_updateToggle(s.currentTarget.checked,`#${t.id}`,n,e)};fcn_updateToggle(FcnFormatting.get()[n],`#${t.id}`,n,{save:!1,...e})})),_$$("#reader-settings-sensitive-content-toggle").forEach((t=>{const e={toggleClass:"hide-sensitive",invertClass:!0,sensitiveContent:!0},n="show-sensitive-content";t.onclick=s=>{fcn_updateToggle(s.currentTarget.checked,`#${t.id}`,n,e)};fcn_updateToggle(FcnFormatting.get()[n],`#${t.id}`,n,{save:!1,...e})}));