From 83bba1ff2ed203b7e2d7bf5ed64a17b1a95e8180 Mon Sep 17 00:00:00 2001 From: Andrew Polk Date: Thu, 21 Nov 2024 10:19:36 -0700 Subject: [PATCH] chore: Re-prettier bloom-player-core --- src/bloom-player-core.tsx | 387 ++++++++++++++++++++------------------ 1 file changed, 199 insertions(+), 188 deletions(-) diff --git a/src/bloom-player-core.tsx b/src/bloom-player-core.tsx index 7ce79eb..c7cc8eb 100644 --- a/src/bloom-player-core.tsx +++ b/src/bloom-player-core.tsx @@ -23,12 +23,12 @@ import { reportPlaybackComplete, sendMessageToHost, setAmbientAnalyticsProperties, - updateBookProgressReport + updateBookProgressReport, } from "./externalContext"; import { clearSoundLog, reportSoundsLogged, - sendStringToBloomApi + sendStringToBloomApi, } from "./videoRecordingSupport"; import LangData from "./langData"; import Replay from "@material-ui/icons/Replay"; @@ -49,7 +49,7 @@ import "jquery.nicescroll"; import { getQueryStringParamAndUnencode } from "./utilities/urlUtils"; import { kLocalStorageDurationKey, - kLocalStorageBookUrlKey + kLocalStorageBookUrlKey, } from "./bloomPlayerAnalytics"; import { autoPlayType } from "./bloom-player-controls"; import { @@ -72,7 +72,7 @@ import { hidingPage as hidingNarrationPage, pageHasAudio, setIncludeImageDescriptions, - playAllSentences + playAllSentences, } from "./narration"; import { logSound } from "./videoRecordingSupport"; import { playSoundOf } from "./dragActivityRuntime"; @@ -123,7 +123,7 @@ interface IProps { // Provides the client a way to switch page numbers. It would feel more natural and React-y to // just pass current page number to bloom-player-controls as a property, but I don't think regenerating the whole // bloom-player-core to switch page numbers is a great idea. - setCurrentPage?: (pageNo: number) => void + setCurrentPage?: (pageNo: number) => void, ) => void; // A callback the client may supply to be notified whether navigation buttons are being hidden for this page. @@ -277,7 +277,7 @@ export class BloomPlayerCore extends React.Component { // notifications from narration.ts etc about duration etc. BloomPlayerCore.currentPagePlayer = this; this.legacyQuestionHandler = new LegacyQuestionHandler( - props.locationOfDistFolder + props.locationOfDistFolder, ); } @@ -292,7 +292,7 @@ export class BloomPlayerCore extends React.Component { loadErrorHtml: "", ignorePhonyClick: false, isFinishUpForNewBookComplete: false, - inPauseForced: false + inPauseForced: false, }; // The book url we were passed as a URL param. @@ -330,15 +330,15 @@ export class BloomPlayerCore extends React.Component { // To get this to fire consistently no matter where the focus is, // we have to attach to the document itself. No level of react component // seems to work (using the OnKeyDown prop). So we use good ol'-fashioned js. - document.addEventListener("keydown", e => - this.handleDocumentLevelKeyDown(e) + document.addEventListener("keydown", (e) => + this.handleDocumentLevelKeyDown(e), ); // Clicking on any element that has a data-href attribute will be treated as a link. // This is the simplest way to handle such links that may be scattered on different // types of elements throughout the book. See BL-13879. - document.addEventListener("click", e => - this.handleDocumentLevelClick(e) + document.addEventListener("click", (e) => + this.handleDocumentLevelClick(e), ); // We only need to add these body-level listeners once. @@ -390,7 +390,7 @@ export class BloomPlayerCore extends React.Component { return; } const targetElement = (e.target as HTMLElement).closest( - "[data-href]" + "[data-href]", ) as HTMLElement; if (targetElement && targetElement.attributes["data-href"]) { const href = targetElement.attributes["data-href"].value as string; @@ -468,10 +468,10 @@ export class BloomPlayerCore extends React.Component { private repairFF60Offset() { try { let wrapper = document.getElementsByClassName( - "swiper-wrapper" + "swiper-wrapper", )[0] as HTMLElement; let current = document.getElementsByClassName( - "swiper-slide-active" + "swiper-slide-active", )[0] as HTMLElement; if (wrapper && current && this.msToContinueFF60RepairChecks > 0) { let error = @@ -486,7 +486,7 @@ export class BloomPlayerCore extends React.Component { paddingPx.length === 0 ? 0 : parseFloat( - paddingPx.substring(0, paddingPx.length - 2) + paddingPx.substring(0, paddingPx.length - 2), ); wrapper.style.paddingLeft = padding + error / scale + "px"; } @@ -506,7 +506,7 @@ export class BloomPlayerCore extends React.Component { // don't consume extra power forever doing this check. private msToContinueFF60RepairChecks = 0; - private handleDocumentLevelKeyDown = e => { + private handleDocumentLevelKeyDown = (e) => { if (e.key === "Home") { this.goToFirstPage(); e.preventDefault(); @@ -561,12 +561,12 @@ export class BloomPlayerCore extends React.Component { if (slashIndex > encodedSlashIndex) { filename = this.sourceUrl.substring( slashIndex + 1, - this.sourceUrl.length + this.sourceUrl.length, ); } else { filename = this.sourceUrl.substring( encodedSlashIndex + 3, - this.sourceUrl.length + this.sourceUrl.length, ); } // Note, The current best practice is actually to have the htm file always be "index.htm". @@ -580,7 +580,7 @@ export class BloomPlayerCore extends React.Component { this.urlPrefix = haveFullPath ? this.sourceUrl.substring( 0, - Math.max(slashIndex, encodedSlashIndex) + Math.max(slashIndex, encodedSlashIndex), ) : this.sourceUrl; this.music.urlPrefix = this.urlPrefix; @@ -593,28 +593,27 @@ export class BloomPlayerCore extends React.Component { const distributionPromise = axios .get(this.fullUrl(".distribution")) .then( - result => { + (result) => { return result; }, // Very possibly the BloomPUB doesn't have this file. The only way to find this // out is by the request failing. We don't consider this a 'real' failure and // just fulfil the promise with an object indicating that distribution is an // empty string. - error => { + (error) => { return { data: "" }; - } + }, ); const htmlPromise = axios.get(urlOfBookHtmlFile); const metadataPromise = axios.get(this.fullUrl("meta.json")); Promise.all([htmlPromise, metadataPromise, distributionPromise]) - .then(result => { - const [ - htmlResult, - metadataResult, - distributionResult - ] = result; + .then((result) => { + const [htmlResult, metadataResult, distributionResult] = + result; this.metaDataObject = metadataResult?.data; - this.distributionSource = (distributionResult as any).data; + this.distributionSource = ( + distributionResult as any + ).data; // Note: we do NOT want to try just making an HtmlElement (e.g., document.createElement("html")) // and setting its innerHtml, since that leads to the browser trying to load all the // urls referenced in the book, which is a waste and also won't work because we @@ -623,13 +622,13 @@ export class BloomPlayerCore extends React.Component { // we *think* bookDoc and bookHtmlElement get garbage collected const bookDoc = parser.parseFromString( htmlResult?.data, - "text/html" + "text/html", ); - const bookHtmlElement = bookDoc.documentElement as HTMLHtmlElement; + const bookHtmlElement = + bookDoc.documentElement as HTMLHtmlElement; - const body = bookHtmlElement.getElementsByTagName( - "body" - )[0]; + const body = + bookHtmlElement.getElementsByTagName("body")[0]; this.bookInfo.setSomeBookInfoFromBody(body); // contains conditions to limit this to one time only after assembleStyleSheets has completed. @@ -643,20 +642,21 @@ export class BloomPlayerCore extends React.Component { this.videoList = this.getVideoList(bookDoc); } - this.animation.PlayAnimations = this.bookInfo.playAnimations; + this.animation.PlayAnimations = + this.bookInfo.playAnimations; this.collectBodyAttributes(body); this.makeNonEditable(body); this.htmlElement = bookHtmlElement; - const firstPage = bookHtmlElement.getElementsByClassName( - "bloom-page" - )[0]; + const firstPage = + bookHtmlElement.getElementsByClassName( + "bloom-page", + )[0]; this.originalPageClass = "Device16x9Portrait"; if (firstPage) { - this.originalPageClass = BloomPlayerCore.getPageSizeClass( - firstPage - ); + this.originalPageClass = + BloomPlayerCore.getPageSizeClass(firstPage); } // enhance: make this callback thing into a promise this.legacyQuestionHandler.generateQuizPagesFromLegacyJSON( @@ -665,10 +665,10 @@ export class BloomPlayerCore extends React.Component { this.originalPageClass, () => { this.finishUp(); - } + }, ); }) - .catch(err => this.HandleLoadingError(err)); + .catch((err) => this.HandleLoadingError(err)); } else if ( // Still the same book, we've already loaded the page data. But we may need to adjust the orientation // class on each (nontrivial) page if @@ -721,7 +721,7 @@ export class BloomPlayerCore extends React.Component { // for each page change and add any needed niceScrolls anyway. See BL-11070. this.rootDiv ?.querySelectorAll(kSelectorForPotentialNiceScrollElements) - .forEach(group => { + .forEach((group) => { // The type definition is not correct for getNiceScroll; we expect it to return an array. const groupNiceScroll = $(group).getNiceScroll() as any; if (groupNiceScroll && groupNiceScroll.length > 0) { @@ -780,7 +780,7 @@ export class BloomPlayerCore extends React.Component { this.setState({ isLoading: false, loadFailed: true, - loadErrorHtml: error.message + loadErrorHtml: error.message, }); } } @@ -821,12 +821,11 @@ export class BloomPlayerCore extends React.Component { // convert from the NamedNodeMap to a simple object: var x = {}; for (var i = 0; i < originalBodyElement.attributes.length; i++) { - x[ - originalBodyElement.attributes.item(i)!.nodeName - ] = originalBodyElement.attributes.item(i)!.nodeValue; + x[originalBodyElement.attributes.item(i)!.nodeName] = + originalBodyElement.attributes.item(i)!.nodeValue; } this.setState({ - importedBodyAttributes: x + importedBodyAttributes: x, }); } @@ -848,14 +847,14 @@ export class BloomPlayerCore extends React.Component { msg = "

This book (or some part of it) was not found.

"; if (axiosError.config && axiosError.config.url) { msg += `

${htmlEncode( - axiosError.config.url + axiosError.config.url, )}

`; } } this.setState({ isLoading: false, loadFailed: true, - loadErrorHtml: msg + loadErrorHtml: msg, }); } @@ -935,9 +934,9 @@ export class BloomPlayerCore extends React.Component { // This allows the page numbers it shows as labels to reflect the actual page numbers shown on the // page, which typically don't correspond to the page index, since xmatter pages are not numbered. pageNumbers: Array.from(pages).map( - p => p.getAttribute("data-page-number") ?? "" + (p) => p.getAttribute("data-page-number") ?? "", ), - isRtl: this.metaDataObject.isRtl + isRtl: this.metaDataObject.isRtl, }); } if (isNewBook) { @@ -967,7 +966,7 @@ export class BloomPlayerCore extends React.Component { this.activityManager.initializePageHtml( this.urlPrefix, page, - swiperContent.length + swiperContent.length, ); if ( @@ -986,15 +985,16 @@ export class BloomPlayerCore extends React.Component { if (this.metaDataObject) { this.bookInfo.setSomeBookInfoFromMetadata( this.metaDataObject, - body + body, ); this.reportBookOpened(body); } if (this.props.controlsCallback) { - const languages = LangData.createLangDataArrayFromDomAndMetadata( - body, - this.metaDataObject - ); + const languages = + LangData.createLangDataArrayFromDomAndMetadata( + body, + this.metaDataObject, + ); this.hasImageDescriptions = doesBookHaveImageDescriptions(body); // Tell BloomPlayerControls which languages are available for the Language Menu // and whether or not to bother with the readImageDescriptions toggle. @@ -1003,7 +1003,7 @@ export class BloomPlayerCore extends React.Component { this.hasImageDescriptions, (pageNumber: number) => { this.swiperInstance?.slideTo(pageNumber); - } + }, ); } } @@ -1012,7 +1012,7 @@ export class BloomPlayerCore extends React.Component { // Otherwise, it wreaks havoc on scoped styles. See BL-9504. if (isNewBook) { const combinedStyle = await this.assembleStyleSheets( - this.htmlElement + this.htmlElement, ); // We're about to start rendering with isLoading false. That means the spinning circle is // replaced with a swiper control showing the actual book contents. We need to do certain @@ -1028,12 +1028,12 @@ export class BloomPlayerCore extends React.Component { pageIdToIndexMap: pageMap, styleRules: combinedStyle, isLoading: false, - currentSwiperIndex: this.props.startPage ?? 0 + currentSwiperIndex: this.props.startPage ?? 0, }); } else { this.setState({ pages: swiperContent, - isLoading: false + isLoading: false, }); } @@ -1063,10 +1063,10 @@ export class BloomPlayerCore extends React.Component { this.showingPage(startPage); //This allows a user to tab to the prev/next buttons, and also makes the focus() call work const nextButton = document.getElementsByClassName( - "swiper-button-next" + "swiper-button-next", )[0] as HTMLElement; const prevButton = document.getElementsByClassName( - "swiper-button-prev" + "swiper-button-prev", )[0] as HTMLElement; prevButton?.setAttribute("tabindex", "4"); @@ -1105,8 +1105,8 @@ export class BloomPlayerCore extends React.Component { // it wreaks havoc on scoped styles. See BL-9504. private showOrHideL1OnlyText(page: Element, show: boolean) { page.querySelectorAll( - ".coverBottomBookTopic, .coverBottomLangName" - ).forEach(elementToShowOrHide => { + ".coverBottomBookTopic, .coverBottomLangName", + ).forEach((elementToShowOrHide) => { // bloom-content1 should never be hidden here, nor should anything if show is true. if ( show || @@ -1128,7 +1128,7 @@ export class BloomPlayerCore extends React.Component { ) { LocalizationManager.localizePages( document.body, - this.bookInfo.getPreferredTranslationLanguages() + this.bookInfo.getPreferredTranslationLanguages(), ); this.isPagesLocalized = true; } @@ -1136,7 +1136,7 @@ export class BloomPlayerCore extends React.Component { // We need named functions for each LiteEvent handler, so that we can unsubscribe them // when we are about to unmount. - private handlePageVideoComplete = pageVideoData => { + private handlePageVideoComplete = (pageVideoData) => { // Verify we're on the current page before playing audio (BL-10039) // If the user if flipping pages rapidly, video completed events can overlap. if (pageVideoData!.page === BloomPlayerCore.currentPage) { @@ -1168,7 +1168,7 @@ export class BloomPlayerCore extends React.Component { this.video = new Video(); this.video.PageVideoComplete = new LiteEvent(); this.video.PageVideoComplete.subscribe( - this.handlePageVideoComplete + this.handlePageVideoComplete, ); } if (!this.animation) { @@ -1180,7 +1180,7 @@ export class BloomPlayerCore extends React.Component { PlayCompleted.subscribe(this.handlePlayCompleted); listenForPlayDuration(this.storeAudioAnalytics.bind(this)); ToggleImageDescription.subscribe( - this.handleToggleImageDescription.bind(this) + this.handleToggleImageDescription.bind(this), ); // allows narration to ask whether swiping to this page is still in progress. // This doesn't seem to be super reliable, so that narration code also keeps track of @@ -1188,7 +1188,7 @@ export class BloomPlayerCore extends React.Component { setTestIsSwipeInProgress(() => { return this.swiperInstance?.animating; }); - setLogNarration(url => logSound(url, 1)); + setLogNarration((url) => logSound(url, 1)); if (!this.music) { this.music = new Music(); @@ -1207,7 +1207,7 @@ export class BloomPlayerCore extends React.Component { let url = this.props.url; if (url === undefined || "" === url.trim()) { throw new Error( - "The url parameter was empty. It should point to the url of a book." + "The url parameter was empty. It should point to the url of a book.", ); } // Bloom Publish Preview uses this so that we get spinning wheel while working on making the bloomd @@ -1253,15 +1253,16 @@ export class BloomPlayerCore extends React.Component { } private getAllPrimaryImageContainersOnPage() { - const unfilteredContainers = this.htmlElement?.ownerDocument.getElementsByClassName( - "bloom-imageContainer" - ); + const unfilteredContainers = + this.htmlElement?.ownerDocument.getElementsByClassName( + "bloom-imageContainer", + ); if (!unfilteredContainers) { return []; } return Array.from(unfilteredContainers).filter( (el: Element) => - el.parentElement!.closest(".bloom-imageContainer") === null + el.parentElement!.closest(".bloom-imageContainer") === null, ) as HTMLElement[]; } @@ -1271,20 +1272,20 @@ export class BloomPlayerCore extends React.Component { } try { const langVernacular = this.props.activeLanguageCode; - this.getAllPrimaryImageContainersOnPage().forEach(container => { + this.getAllPrimaryImageContainersOnPage().forEach((container) => { Array.from( - container.getElementsByClassName("bloom-textOverPicture") - ).forEach(top => { + container.getElementsByClassName("bloom-textOverPicture"), + ).forEach((top) => { const editable = Array.from( - top.getElementsByClassName("bloom-editable") - ).find(e => e.getAttribute("lang") === langVernacular); + top.getElementsByClassName("bloom-editable"), + ).find((e) => e.getAttribute("lang") === langVernacular); if (editable) { const alternatesString = editable.getAttribute( - "data-bubble-alternate" + "data-bubble-alternate", ); if (alternatesString) { const alternate = JSON.parse( - alternatesString.replace(/`/g, '"') + alternatesString.replace(/`/g, '"'), ) as IAlternate; top.setAttribute("style", alternate.style); } @@ -1292,17 +1293,20 @@ export class BloomPlayerCore extends React.Component { }); // If we have an alternate SVG for this language, activate it. const altSvg = Array.from( - container.getElementsByClassName("comical-alternate") - ).find(svg => svg.getAttribute("data-lang") === langVernacular); + container.getElementsByClassName("comical-alternate"), + ).find( + (svg) => svg.getAttribute("data-lang") === langVernacular, + ); // if we don't find one, don't need to do anything. // Possibly this image container doesn't have overlays. Possibly // the right svg is already switched to be the active one. Possibly the // book was made by an older version of Bloom without multilingual overlay // support. if (altSvg) { - const currentSvg = container.getElementsByClassName( - "comical-generated" - )[0]; + const currentSvg = + container.getElementsByClassName( + "comical-generated", + )[0]; if (currentSvg) { // should always be true // demote it to alternate @@ -1358,7 +1362,7 @@ export class BloomPlayerCore extends React.Component { this.htmlElement, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); const visibilityClass = "bloom-visibility-code-on"; @@ -1369,10 +1373,10 @@ export class BloomPlayerCore extends React.Component { iTranGrps++ ) { const groupElement = translationGroupDivs.snapshotItem( - iTranGrps + iTranGrps, ) as HTMLElement; const dataDefaultLangsAttr = groupElement.getAttribute( - "data-default-languages" + "data-default-languages", ); // Split the string into array form instead, using delimiters "," or " " @@ -1387,7 +1391,7 @@ export class BloomPlayerCore extends React.Component { dataDefaultLangs.includes("L1") || BloomPlayerCore.areStringsEqualInvariantCultureIgnoreCase( dataDefaultLangs[0], - "auto" + "auto", ); const childElts = groupElement.childNodes; @@ -1405,14 +1409,14 @@ export class BloomPlayerCore extends React.Component { // (But keep going...the first run might NOT be usingDefaultLang.) divElement.setAttribute( "data-original-class", - divElement.getAttribute("class") || "" + divElement.getAttribute("class") || "", ); } if (usingDefaultLang) { // go back to the original classes from bloom desktop divElement.setAttribute( "class", - divElement.getAttribute("data-original-class") || "" + divElement.getAttribute("data-original-class") || "", ); } else if (isVernacularBlock) { // only the one that matches activeLanguage should be visible @@ -1421,11 +1425,13 @@ export class BloomPlayerCore extends React.Component { divElement.classList.add(visibilityClass); // We don't want any behavior triggered by things like bloom-contentNational1, for example. // It may be that language, but in this state it's more important that it is the selected book language. - Array.from(divElement.classList).forEach(className => { - if (className.startsWith("bloom-content")) { - divElement.classList.remove(className); - } - }); + Array.from(divElement.classList).forEach( + (className) => { + if (className.startsWith("bloom-content")) { + divElement.classList.remove(className); + } + }, + ); // Depending on whether the field is controlled by the appearance system, one of these // classes may activate style rules appropriate to the main book language. divElement.classList.add("bloom-content1"); @@ -1443,7 +1449,7 @@ export class BloomPlayerCore extends React.Component { private static areStringsEqualInvariantCultureIgnoreCase( a: string, - b: string + b: string, ) { return a.localeCompare(b, "en-US", { sensitivity: "accent" }) === 0; } @@ -1458,8 +1464,8 @@ export class BloomPlayerCore extends React.Component { public componentWillUnmount() { this.pauseAllMultimedia(); - document.removeEventListener("keydown", e => - this.handleDocumentLevelKeyDown(e) + document.removeEventListener("keydown", (e) => + this.handleDocumentLevelKeyDown(e), ); this.unsubscribeAllEvents(); } @@ -1501,7 +1507,8 @@ export class BloomPlayerCore extends React.Component { // by our external container (Bloom Reader, Bloom Library, etc.) // when the parent reader determines that the session reading this book is finished. private sendUpdateOfBookProgressReportToExternalContext() { - const properties = this.bookInteraction.getProgressReportPropertiesForAnalytics(); + const properties = + this.bookInteraction.getProgressReportPropertiesForAnalytics(); // Pass the completed report to the externalContext version of this method which actually sends it. updateBookProgressReport("Pages Read", properties); } @@ -1514,11 +1521,11 @@ export class BloomPlayerCore extends React.Component { body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); for (let iedit = 0; iedit < editable.snapshotLength; iedit++) { (editable.snapshotItem(iedit) as HTMLElement).removeAttribute( - "contenteditable" + "contenteditable", ); } } @@ -1529,7 +1536,7 @@ export class BloomPlayerCore extends React.Component { this.bookInfo.canRotate, this.props.landscape, this.props.useOriginalPageSize || this.bookInfo.hasFeature("comic"), - this.originalPageClass + this.originalPageClass, ); } @@ -1550,7 +1557,7 @@ export class BloomPlayerCore extends React.Component { bookCanRotate: boolean, showLandscape: boolean, useOriginalPageSize: boolean, - originalPageClass: string + originalPageClass: string, ): boolean { let landscape = false; const sizeClass = this.getPageSizeClass(page); @@ -1593,7 +1600,7 @@ export class BloomPlayerCore extends React.Component { page, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); for (let j = 0; j < srcElts.snapshotLength; j++) { @@ -1613,7 +1620,7 @@ export class BloomPlayerCore extends React.Component { page, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); const regexp = new RegExp(/background-image:url\(['"](.*)['"]\)/); @@ -1632,7 +1639,7 @@ export class BloomPlayerCore extends React.Component { regexp, // if we weren't using lazy-load: // "background-image:url('" + newUrl + "'" - "" + "", ); item.setAttribute("style", newStyle); item.setAttribute("data-background", newUrl); @@ -1660,9 +1667,9 @@ export class BloomPlayerCore extends React.Component { // a corresponding woff font in a standard location. We may even be able to pay to // provide some fonts there for book previewing that are NOT embeddable. private makeFontStylesheet(href: string): void { - axios.get(href).then(result => { + axios.get(href).then((result) => { let stylesheet = document.getElementById( - "fontCssStyleSheet" + "fontCssStyleSheet", ) as HTMLStyleElement; if (!stylesheet) { stylesheet = document.createElement("style"); @@ -1676,7 +1683,7 @@ export class BloomPlayerCore extends React.Component { // single quotes, and double quotes. Note that we also have to // handle possible parentheses in the file name. /src:url\(['"]?(.*\.[^\)'"]*)['"]?\)/g, - "src:url('" + prefix + "/$1')" + "src:url('" + prefix + "/$1')", ); }); // no catch clause...if there's no fonts.css, we should never get a 'then' and @@ -1688,7 +1695,7 @@ export class BloomPlayerCore extends React.Component { // content go, because @font-face rules don't work there. private makeAndikaStylesheet(): void { let stylesheet = document.getElementById( - "andikaCssStyleSheet" + "andikaCssStyleSheet", ) as HTMLStyleElement; if (!stylesheet) { stylesheet = document.createElement("style"); @@ -1831,7 +1838,7 @@ export class BloomPlayerCore extends React.Component { doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); const promises: Array> = []; for (let i = 0; i < linkElts.snapshotLength; i++) { @@ -1854,12 +1861,12 @@ export class BloomPlayerCore extends React.Component { try { const results = await axios.all( - promises.map(promise => + promises.map((promise) => promise.catch( // if one stylesheet doesn't exist or whatever, keep going - () => undefined - ) - ) + () => undefined, + ), + ), ); let combinedStyle = ""; @@ -1870,7 +1877,7 @@ export class BloomPlayerCore extends React.Component { doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); for (let k = 0; k < styleElts.snapshotLength; k++) { const styleElt = styleElts.snapshotItem(k) as HTMLElement; @@ -1878,10 +1885,10 @@ export class BloomPlayerCore extends React.Component { } // then add the stylesheet contents we just retrieved - results.forEach(result => { + results.forEach((result) => { if (result && result.data) { console.log( - "Loaded stylesheet: " + JSON.stringify(result.config) + "Loaded stylesheet: " + JSON.stringify(result.config), ); combinedStyle += result.data; @@ -1893,10 +1900,10 @@ export class BloomPlayerCore extends React.Component { // We have to check for both for older books. if ( result.config!.url!.endsWith( - "/defaultLangStyles.css" + "/defaultLangStyles.css", ) || result.config!.url!.endsWith( - "/settingsCollectionStyles.css" + "/settingsCollectionStyles.css", ) ) { this.bookInfo.setLanguage2And3(result.data); @@ -1909,7 +1916,7 @@ export class BloomPlayerCore extends React.Component { // We're using this instead of .bloom-page directly so that a selector like `:root .bloom-page` would still work. combinedStyle = combinedStyle.replace( /:root/g, - ".bloomPlayer-page" + ".bloomPlayer-page", ); //console.log("***combinedStyle", combinedStyle); return combinedStyle; @@ -1945,7 +1952,7 @@ export class BloomPlayerCore extends React.Component { } private getPlayerOptionsForPage( - bloomPage: HTMLElement + bloomPage: HTMLElement, ): IPlayerPageOptions | undefined { if (!bloomPage) { return undefined; @@ -1966,7 +1973,7 @@ export class BloomPlayerCore extends React.Component { "getPlayerOptionsForPage failed to parse json: " + optionJson + " with error " + - e.message + e.message, ); return; } @@ -1994,14 +2001,14 @@ export class BloomPlayerCore extends React.Component {
); } setIncludeImageDescriptions( - this.props.shouldReadImageDescriptions && this.hasImageDescriptions + this.props.shouldReadImageDescriptions && this.hasImageDescriptions, ); const swiperParams: any = { // This is how we'd expect to make the next/prev buttons show up. @@ -2012,7 +2019,7 @@ export class BloomPlayerCore extends React.Component { // nextEl: ".swiper-button-next", // prevEl: ".swiper-button-prev" // }, - getSwiper: s => { + getSwiper: (s) => { this.swiperInstance = s; if (this.metaDataObject.isRtl && this.swiperInstance) { // These kluges cause swiper to display the pages in reverse order. @@ -2084,11 +2091,11 @@ export class BloomPlayerCore extends React.Component { // connection.. We want SOME limit so // we don't keep using power for hours if the device is left on this page. slideChangeTransitionEnd: () => - (this.msToContinueFF60RepairChecks = 30000) + (this.msToContinueFF60RepairChecks = 30000), }, keyboard: { enabled: true, - onlyInViewport: false + onlyInViewport: false, }, // Disable preloading of all images preloadImages: false, @@ -2102,10 +2109,10 @@ export class BloomPlayerCore extends React.Component { lazy: { loadPrevNext: true, loadOnTransitionStart: true, - loadPrevNextAmount: 2 + loadPrevNextAmount: 2, }, // This seems make it unnecessary to call Swiper.update at the end of componentDidUpdate. - shouldSwiperUpdate: true + shouldSwiperUpdate: true, }; if (this.startingUpSwiper) { // When we first render swiper, we need to force it to the right page. But not later, @@ -2148,7 +2155,7 @@ export class BloomPlayerCore extends React.Component { ? " " + this.props.extraClassNames : "") } - ref={bloomplayer => (this.rootDiv = bloomplayer)} + ref={(bloomplayer) => (this.rootDiv = bloomplayer)} > {
{ + onClick={(e) => { if ( !this.state.ignorePhonyClick && // if we're dragging, that isn't a click we want to propagate this.props.onContentClick && @@ -2182,13 +2189,13 @@ export class BloomPlayerCore extends React.Component { // I tried adding another click handler to the video container with stopPropagation, // but for some reason it didn't work. !(e.target as HTMLElement).closest( - ".bloom-videoContainer" + ".bloom-videoContainer", ) ) { this.props.onContentClick(e); } this.setState({ - ignorePhonyClick: false + ignorePhonyClick: false, }); }} > @@ -2223,19 +2230,21 @@ export class BloomPlayerCore extends React.Component { .hasAppearanceSystem ? "appearance-system" : "" - } ${this.state - .importedBodyAttributes[ - "class" - ] ?? ""}`} + } ${ + this.state + .importedBodyAttributes[ + "class" + ] ?? "" + }`} // Note: the contents of `slide` are what was in the .htm originally. // So you would expect that this would replace any changes made to the dom by the activity or other code. // You would expect that we would lose the answers a user made in an activity. // However it appears that React doesn't notice those changes and thus does nothing when we try to set // the HTML here to what it was originally; instead changes to the DOM are preserved. dangerouslySetInnerHTML={{ - __html: slide + __html: slide, }} - ref={div => + ref={(div) => this.fixInternalHyperlinks(div) } /> @@ -2269,7 +2278,7 @@ export class BloomPlayerCore extends React.Component { : "") } onClick={() => this.slidePrevious()} - onTouchStart={e => { + onTouchStart={(e) => { this.setState({ ignorePhonyClick: true }); // not needed, touch still causes a click, this can cause double page change //this.slidePrevious(); @@ -2284,7 +2293,7 @@ export class BloomPlayerCore extends React.Component { titleAccess={LocalizationManager.getTranslation( "Button.Prev", this.props.preferredUiLanguages, - "Previous Page" + "Previous Page", )} /> ) : ( @@ -2292,7 +2301,7 @@ export class BloomPlayerCore extends React.Component { titleAccess={LocalizationManager.getTranslation( "Button.Prev", this.props.preferredUiLanguages, - "Previous Page" + "Previous Page", )} /> )} @@ -2311,7 +2320,7 @@ export class BloomPlayerCore extends React.Component { : "") } onClick={() => this.slideNext()} - onTouchStart={e => { + onTouchStart={(e) => { this.setState({ ignorePhonyClick: true }); // not needed, touch still causes a click, this can cause double page change //this.slideNext(); @@ -2323,7 +2332,7 @@ export class BloomPlayerCore extends React.Component { titleAccess={LocalizationManager.getTranslation( "Button.Next", this.props.preferredUiLanguages, - "Next Page" + "Next Page", )} /> ) : ( @@ -2331,7 +2340,7 @@ export class BloomPlayerCore extends React.Component { titleAccess={LocalizationManager.getTranslation( "Button.Next", this.props.preferredUiLanguages, - "Next Page" + "Next Page", )} /> )} @@ -2352,21 +2361,21 @@ export class BloomPlayerCore extends React.Component { return; } const anchors = Array.from(div.getElementsByTagName("a") ?? []); - anchors.forEach(a => { + anchors.forEach((a) => { const href = a.getAttribute("href"); // not a.href, which has the full page address prepended. if (href?.startsWith("#")) { const pageId = href.substring(1); const pageNum = this.state.pageIdToIndexMap[pageId]; if (pageNum !== undefined) { a.href = ""; // may not be needed, on its own was unsuccessful in stopping attempted default navigation - a.onclick = ev => { + a.onclick = (ev) => { ev.preventDefault(); // don't try to follow the link, other than by the slideTo below ev.stopPropagation(); // don't allow parent listeners, particularly the one that toggles the nav bar this.swiperInstance.slideTo(pageNum); }; } else { // no other kind of internal link makes sense, so let them be ignored. - a.onclick = ev => { + a.onclick = (ev) => { ev.preventDefault(); ev.stopPropagation(); }; @@ -2467,7 +2476,7 @@ export class BloomPlayerCore extends React.Component { return null; // unexpected } const bloomPage = swiperPage.getElementsByClassName( - "bloom-page" + "bloom-page", )[0] as HTMLElement; return bloomPage; } @@ -2522,7 +2531,7 @@ export class BloomPlayerCore extends React.Component { options && options.hideNavigation ? true : false; if (this.props.hidingNavigationButtonsCallback) { this.props.hidingNavigationButtonsCallback( - this.currentPageHidesNavigationButtons + this.currentPageHidesNavigationButtons, ); } // Values this sets are used in the render of the new page, so it must NOT @@ -2561,7 +2570,7 @@ export class BloomPlayerCore extends React.Component { this.props.reportPageProperties({ hasAudio: pageHasAudio(bloomPage), hasMusic: this.music.pageHasMusic(bloomPage), - hasVideo: BloomPlayerCore.currentPageHasVideo + hasVideo: BloomPlayerCore.currentPageHasVideo, }); } @@ -2570,10 +2579,10 @@ export class BloomPlayerCore extends React.Component { this.sendUpdateOfBookProgressReportToExternalContext(); // these were hard to get right. If you change them, make sure to test both mouse and touch mode (simulated in Chrome) - this.swiperInstance.params.noSwiping = this.activityManager.getActivityAbsorbsDragging(); - this.swiperInstance.params.touchRatio = this.activityManager.getActivityAbsorbsDragging() - ? 0 - : 1; + this.swiperInstance.params.noSwiping = + this.activityManager.getActivityAbsorbsDragging(); + this.swiperInstance.params.touchRatio = + this.activityManager.getActivityAbsorbsDragging() ? 0 : 1; // didn't seem to help: this.swiperInstance.params.allowTouchMove = false; if (this.activityManager.getActivityAbsorbsTyping()) { this.swiperInstance.keyboard.disable(); @@ -2583,7 +2592,7 @@ export class BloomPlayerCore extends React.Component { BloomPlayerCore.addScrollbarsToPage(bloomPage); const soundItems = Array.from( - bloomPage.querySelectorAll("[data-sound]") + bloomPage.querySelectorAll("[data-sound]"), ); soundItems.forEach((elt: HTMLElement) => { elt.addEventListener("click", playSoundOf); @@ -2665,7 +2674,7 @@ export class BloomPlayerCore extends React.Component { (entries, ob) => { // called more-or-less immediately for each child, but after the // loop creates them all. - entries.forEach(entry => { + entries.forEach((entry) => { countOfObserversThatHaveReported++; ob.unobserve(entry.target); // don't want to keep getting them, or leak observers // console.log("bounding: "); @@ -2676,7 +2685,7 @@ export class BloomPlayerCore extends React.Component { // "ratio: " + entry.intersectionRatio // ); var isBubble = !!entry.target.closest( - ".bloom-textOverPicture" + ".bloom-textOverPicture", ); // In bloom desktop preview, we set width to 200% and then scale down by 50%. // This can lead to intersection ratios very slightly less than 1, probably due @@ -2720,15 +2729,16 @@ export class BloomPlayerCore extends React.Component { const overflow = (1 - entry.intersectionRatio) * entry.target.clientHeight; - const lineHeightPx = window.getComputedStyle( - entry.target - ).lineHeight; + const lineHeightPx = + window.getComputedStyle( + entry.target, + ).lineHeight; const lineHeight = parseFloat( // remove the trailing "px" lineHeightPx.substring( 0, - lineHeightPx.length - 2 - ) + lineHeightPx.length - 2, + ), ); overflowing = overflow > @@ -2738,20 +2748,21 @@ export class BloomPlayerCore extends React.Component { if ( overflowing && scrollBlocks.indexOf( - entry.target.parentElement! + entry.target.parentElement!, ) < 0 ) { scrollBlocks.push( - entry.target.parentElement! + entry.target.parentElement!, ); // remove classes incompatible with niceScroll - const group = entry.target.parentElement! - .parentElement!; + const group = + entry.target.parentElement! + .parentElement!; group.classList.remove( - "bloom-vertical-align-center" + "bloom-vertical-align-center", ); group.classList.remove( - "bloom-vertical-align-bottom" + "bloom-vertical-align-bottom", ); if (isBubble) { // This is a way of forcing it not to be display-flex, which doesn't @@ -2759,7 +2770,7 @@ export class BloomPlayerCore extends React.Component { // That library messes with the element style, so it seemed safer // not to do that myself. entry.target.parentElement!.classList.add( - "scrolling-bubble" + "scrolling-bubble", ); } } @@ -2777,16 +2788,16 @@ export class BloomPlayerCore extends React.Component { cursorwidth: "12px", cursorcolor: "#000000", cursoropacitymax: 0.1, - cursorborderradius: "12px" // Make the corner more rounded than the 5px default. + cursorborderradius: "12px", // Make the corner more rounded than the 5px default. }); this.setupSpecialMouseTrackingForNiceScroll( - bloomPage + bloomPage, ); scrollBlocks = []; // Just in case it's possible to get callbacks before we created them all. } }); }, - { root: elt } + { root: elt }, ); countOfObserversExpectedToReport++; observer.observe(firstChild!); @@ -2826,8 +2837,8 @@ export class BloomPlayerCore extends React.Component { eventName, BloomPlayerCore.handlePointerMoveEvent, { - capture: true - } + capture: true, + }, ); } } @@ -2862,7 +2873,7 @@ export class BloomPlayerCore extends React.Component { if ( ev.target instanceof HTMLDivElement && (ev.target as HTMLDivElement).classList.contains( - "nicescroll-cursors" + "nicescroll-cursors", ) ) { (ev.target as HTMLDivElement).setPointerCapture(ev.pointerId); @@ -2892,7 +2903,7 @@ export class BloomPlayerCore extends React.Component { if (!this.bookInteraction.reportedAudioOnCurrentPage) { this.bookInteraction.reportedAudioOnCurrentPage = true; this.bookInteraction.audioPageShown( - BloomPlayerCore.currentPageIndex + BloomPlayerCore.currentPageIndex, ); } this.sendUpdateOfBookProgressReportToExternalContext(); @@ -2912,7 +2923,7 @@ export class BloomPlayerCore extends React.Component { ) { player.bookInteraction.reportedVideoOnCurrentPage = true; player.bookInteraction.videoPageShown( - BloomPlayerCore.currentPageIndex + BloomPlayerCore.currentPageIndex, ); } player.sendUpdateOfBookProgressReportToExternalContext(); @@ -2975,7 +2986,7 @@ export class BloomPlayerCore extends React.Component { if (this.props.shouldReportSoundLog) { sendStringToBloomApi( "/publish/av/startRecording", - this.videoList + this.videoList, ).then(finishUp); return; // don't 'finishUp' until the post returns } @@ -3020,7 +3031,7 @@ export class BloomPlayerCore extends React.Component { } function htmlEncode(str: string): string { - return str.replace("%23", "#").replace(/[\u00A0-\u9999<>\&]/gim, i => { + return str.replace("%23", "#").replace(/[\u00A0-\u9999<>\&]/gim, (i) => { return "&#" + i.charCodeAt(0) + ";"; }); } @@ -3034,7 +3045,7 @@ function doesBookHaveImageDescriptions(body: HTMLBodyElement): boolean { body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); if (imgDescDivs.snapshotLength > 0) return true; // Perhaps the user never split TextBox recordings into segments for image descriptions @@ -3049,7 +3060,7 @@ function doesBookHaveImageDescriptions(body: HTMLBodyElement): boolean { body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null + null, ); return imgDescParas.snapshotLength > 0; }