diff --git a/src/BloomBrowserUI/bookEdit/css/origamiEditing.less b/src/BloomBrowserUI/bookEdit/css/origamiEditing.less index f7f4c1d26736..a300627654b6 100644 --- a/src/BloomBrowserUI/bookEdit/css/origamiEditing.less +++ b/src/BloomBrowserUI/bookEdit/css/origamiEditing.less @@ -145,9 +145,10 @@ top: @ToggleVerticalOffset; width: 100%; display: flex; - justify-content: end; + justify-content: space-between; box-sizing: border-box; } + .origami-toggle { cursor: pointer; margin-right: 19px; @@ -160,6 +161,28 @@ display: inline; } } +.page-settings-button { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + padding: 0; + margin-right: 8px; + border: none; + background-color: transparent; + cursor: pointer; + color: @bloom-purple; + + &:hover { + opacity: 0.8; + } + + svg { + width: 20px; + height: 20px; + } +} // here follows the inner workings of the toggle .onoffswitch { diff --git a/src/BloomBrowserUI/bookEdit/editViewFrame.ts b/src/BloomBrowserUI/bookEdit/editViewFrame.ts index 0c39afffb399..92fb8de70f03 100644 --- a/src/BloomBrowserUI/bookEdit/editViewFrame.ts +++ b/src/BloomBrowserUI/bookEdit/editViewFrame.ts @@ -56,6 +56,7 @@ export { showPageChooserDialog }; import "../lib/errorHandler"; import { showBookSettingsDialog } from "./bookSettings/BookSettingsDialog"; export { showBookSettingsDialog }; +import { showPageSettingsDialog } from "./pageSettings/PageSettingsDialog"; import { showRegistrationDialogForEditTab } from "../react_components/registration/registrationDialog"; export { showRegistrationDialogForEditTab as showRegistrationDialog }; import { showAboutDialog } from "../react_components/aboutDialog"; @@ -261,6 +262,10 @@ export function showEditViewBookSettingsDialog( showBookSettingsDialog(initiallySelectedGroupIndex); } +export function showEditViewPageSettingsDialog() { + showPageSettingsDialog(); +} + export function showAboutDialogInEditTab() { showAboutDialog(); } @@ -319,6 +324,7 @@ interface EditTabBundleApi { showCopyrightAndLicenseDialog: typeof showCopyrightAndLicenseDialog; showEditViewTopicChooserDialog: typeof showEditViewTopicChooserDialog; showEditViewBookSettingsDialog: typeof showEditViewBookSettingsDialog; + showEditViewPageSettingsDialog: typeof showEditViewPageSettingsDialog; showAboutDialogInEditTab: typeof showAboutDialogInEditTab; showRequiresSubscriptionDialog: typeof showRequiresSubscriptionDialog; showRegistrationDialogInEditTab: typeof showRegistrationDialogInEditTab; @@ -356,6 +362,7 @@ window.editTabBundle = { showCopyrightAndLicenseDialog, showEditViewTopicChooserDialog, showEditViewBookSettingsDialog, + showEditViewPageSettingsDialog, showAboutDialogInEditTab, showRequiresSubscriptionDialog, showRegistrationDialogInEditTab, diff --git a/src/BloomBrowserUI/bookEdit/js/origami.ts b/src/BloomBrowserUI/bookEdit/js/origami.ts index e5bb91a50156..2055492a6372 100644 --- a/src/BloomBrowserUI/bookEdit/js/origami.ts +++ b/src/BloomBrowserUI/bookEdit/js/origami.ts @@ -1,5 +1,3 @@ -// not yet: neither bloomEditing nor this is yet a module import {SetupImage} from './bloomEditing'; -/// import { SetupImage } from "./bloomImages"; import { kBloomCanvasClass } from "../toolbox/canvas/canvasElementUtils"; import "../../lib/split-pane/split-pane.js"; @@ -52,6 +50,7 @@ export function setupOrigami() { // the two results, but none of the controls shows up if we leave it all // outside the bloomApi functions. $(".origami-toggle .onoffswitch").change(layoutToggleClickHandler); + $(".page-settings-button").click(pageSettingsButtonClickHandler); if ($(".customPage .marginBox.origami-layout-mode").length) { setupLayoutMode(); @@ -354,11 +353,16 @@ function getAbovePageControlContainer(): JQuery { .getElementsByClassName("bloom-page")[0] ?.getAttribute("data-tool-id") === "game" ) { - return $("
"); + return $( + `
\ +${getPageSettingsButtonHtml()}\ +
`, + ); } return $( - "\ + `\
\ +${getPageSettingsButtonHtml()}\
\
Change Layout
\
\ @@ -369,10 +373,24 @@ function getAbovePageControlContainer(): JQuery { \
\
\ -
", +`, ); } +function getPageSettingsButtonHtml(): string { + // SVG path matches MUI Settings icon + return ``; +} + +function pageSettingsButtonClickHandler(e: Event) { + e.preventDefault(); + post("editView/showPageSettingsDialog"); +} + function getButtons() { const buttons = $( "
", diff --git a/src/BloomBrowserUI/bookEdit/pageSettings/PageSettingsDialog.tsx b/src/BloomBrowserUI/bookEdit/pageSettings/PageSettingsDialog.tsx new file mode 100644 index 000000000000..4ddce0a35e03 --- /dev/null +++ b/src/BloomBrowserUI/bookEdit/pageSettings/PageSettingsDialog.tsx @@ -0,0 +1,442 @@ +import { css } from "@emotion/react"; +import * as React from "react"; +import { + ConfigrCustomStringInput, + ConfigrGroup, + ConfigrPane, + ConfigrSubgroup, +} from "@sillsdev/config-r"; +import { kBloomBlue } from "../../bloomMaterialUITheme"; +import { + BloomDialog, + DialogBottomButtons, + DialogMiddle, + DialogTitle, +} from "../../react_components/BloomDialog/BloomDialog"; +import { useSetupBloomDialog } from "../../react_components/BloomDialog/BloomDialogPlumbing"; +import { + DialogCancelButton, + DialogOkButton, +} from "../../react_components/BloomDialog/commonDialogComponents"; +import { useL10n } from "../../react_components/l10nHooks"; +import { + ColorDisplayButton, + DialogResult, +} from "../../react_components/color-picking/colorPickerDialog"; +import { BloomPalette } from "../../react_components/color-picking/bloomPalette"; +import { getPageIframeBody } from "../../utils/shared"; +import { ShowEditViewDialog } from "../editViewFrame"; +import tinycolor from "tinycolor2"; + +let isOpenAlready = false; + +type IPageSettings = { + page: { + backgroundColor: string; + pageNumberColor: string; + pageNumberBackgroundColor: string; + }; +}; + +const getCurrentPageElement = (): HTMLElement => { + const page = getPageIframeBody()?.querySelector( + ".bloom-page", + ) as HTMLElement | null; + if (!page) { + throw new Error( + "PageSettingsDialog could not find .bloom-page in the page iframe", + ); + } + return page; +}; + +const normalizeToHexOrEmpty = (color: string): string => { + const trimmed = color.trim(); + if (!trimmed) { + return ""; + } + + const parsed = tinycolor(trimmed); + if (!parsed.isValid()) { + return trimmed; + } + + // Treat fully transparent as "not set". + if (parsed.getAlpha() === 0) { + return ""; + } + + return parsed.toHexString().toUpperCase(); +}; + +const getComputedStyleForPage = (page: HTMLElement): CSSStyleDeclaration => { + const view = page.ownerDocument.defaultView; + if (view) { + return view.getComputedStyle(page); + } + return getComputedStyle(page); +}; + +const getCurrentPageBackgroundColor = (): string => { + const page = getCurrentPageElement(); + + const inline = normalizeToHexOrEmpty( + page.style.getPropertyValue("--page-background-color"), + ); + if (inline) return inline; + + const computedVariable = normalizeToHexOrEmpty( + getComputedStyleForPage(page).getPropertyValue( + "--page-background-color", + ), + ); + if (computedVariable) return computedVariable; + + const computedMarginBoxVariable = normalizeToHexOrEmpty( + getComputedStyleForPage(page).getPropertyValue( + "--marginBox-background-color", + ), + ); + if (computedMarginBoxVariable) return computedMarginBoxVariable; + + const computedBackground = normalizeToHexOrEmpty( + getComputedStyleForPage(page).backgroundColor, + ); + return computedBackground || "#FFFFFF"; +}; + +const setOrRemoveCustomProperty = ( + style: CSSStyleDeclaration, + propertyName: string, + value: string, +): void => { + const normalized = normalizeToHexOrEmpty(value); + if (normalized) { + style.setProperty(propertyName, normalized); + } else { + style.removeProperty(propertyName); + } +}; + +const setCurrentPageBackgroundColor = (color: string): void => { + const page = getCurrentPageElement(); + setOrRemoveCustomProperty(page.style, "--page-background-color", color); + setOrRemoveCustomProperty( + page.style, + "--marginBox-background-color", + color, + ); +}; + +const getPageNumberColor = (): string => { + const page = getCurrentPageElement(); + + const inline = normalizeToHexOrEmpty( + page.style.getPropertyValue("--pageNumber-color"), + ); + if (inline) return inline; + + const computed = normalizeToHexOrEmpty( + getComputedStyleForPage(page).getPropertyValue("--pageNumber-color"), + ); + return computed || "#000000"; +}; + +const setPageNumberColor = (color: string): void => { + const page = getCurrentPageElement(); + setOrRemoveCustomProperty(page.style, "--pageNumber-color", color); +}; + +const getPageNumberBackgroundColor = (): string => { + const page = getCurrentPageElement(); + + const inline = normalizeToHexOrEmpty( + page.style.getPropertyValue("--pageNumber-background-color"), + ); + if (inline) return inline; + + const computed = normalizeToHexOrEmpty( + getComputedStyleForPage(page).getPropertyValue( + "--pageNumber-background-color", + ), + ); + return computed || ""; +}; + +const setPageNumberBackgroundColor = (color: string): void => { + const page = getCurrentPageElement(); + setOrRemoveCustomProperty( + page.style, + "--pageNumber-background-color", + color, + ); +}; + +const applyPageSettings = (settings: IPageSettings): void => { + setCurrentPageBackgroundColor(settings.page.backgroundColor); + setPageNumberColor(settings.page.pageNumberColor); + setPageNumberBackgroundColor(settings.page.pageNumberBackgroundColor); +}; + +const PageBackgroundColorPickerForConfigr: React.FunctionComponent<{ + value: string; + disabled: boolean; + onChange: (value: string) => void; +}> = (props) => { + const backgroundColorLabel = useL10n( + "Background Color", + "Common.BackgroundColor", + ); + + return ( + { + if (dialogResult === DialogResult.OK) props.onChange(newColor); + }} + onChange={(newColor) => props.onChange(newColor)} + /> + ); +}; + +const PageNumberColorPickerForConfigr: React.FunctionComponent<{ + value: string; + disabled: boolean; + onChange: (value: string) => void; +}> = (props) => { + const pageNumberColorLabel = useL10n( + "Page Number Color", + "PageSettings.PageNumberColor", + ); + + return ( + { + if (dialogResult === DialogResult.OK) props.onChange(newColor); + }} + onChange={(newColor) => props.onChange(newColor)} + /> + ); +}; + +const PageNumberBackgroundColorPickerForConfigr: React.FunctionComponent<{ + value: string; + disabled: boolean; + onChange: (value: string) => void; +}> = (props) => { + const pageNumberBackgroundColorLabel = useL10n( + "Page Number Background Color", + "PageSettings.PageNumberBackgroundColor", + ); + + return ( + { + if (dialogResult === DialogResult.OK) props.onChange(newColor); + }} + onChange={(newColor) => props.onChange(newColor)} + /> + ); +}; + +export const PageSettingsDialog: React.FunctionComponent = () => { + const { closeDialog, propsForBloomDialog } = useSetupBloomDialog({ + initiallyOpen: true, + dialogFrameProvidedExternally: false, + }); + + const closeDialogAndClearOpenFlag = React.useCallback(() => { + isOpenAlready = false; + closeDialog(); + }, [closeDialog]); + + const pageSettingsTitle = useL10n("Page Settings", "PageSettings.Title"); + const backgroundColorLabel = useL10n( + "Background Color", + "Common.BackgroundColor", + ); + const pageNumberColorLabel = useL10n( + "Page Number Color", + "PageSettings.PageNumberColor", + ); + const pageNumberBackgroundColorLabel = useL10n( + "Page Number Background Color", + "PageSettings.PageNumberBackgroundColor", + ); + + const [initialValues, setInitialValues] = React.useState< + IPageSettings | undefined + >(undefined); + + const [settingsToReturnLater, setSettingsToReturnLater] = React.useState< + IPageSettings | string | undefined + >(undefined); + + // Read after mount so we get the current page's color even if opening this dialog + // is preceded by a save/refresh that updates the page iframe. + React.useEffect(() => { + setInitialValues({ + page: { + backgroundColor: getCurrentPageBackgroundColor(), + pageNumberColor: getPageNumberColor(), + pageNumberBackgroundColor: getPageNumberBackgroundColor(), + }, + }); + }, []); + + const onOk = (): void => { + const rawSettings = settingsToReturnLater ?? initialValues; + if (!rawSettings) { + throw new Error( + "PageSettingsDialog: expected settings to be loaded before OK", + ); + } + + const settings = + typeof rawSettings === "string" + ? (JSON.parse(rawSettings) as IPageSettings) + : rawSettings; + + applyPageSettings(settings); + closeDialogAndClearOpenFlag(); + }; + + const onCancel = ( + _reason?: + | "escapeKeyDown" + | "backdropClick" + | "titleCloseClick" + | "cancelClicked", + ): void => { + if (initialValues) { + applyPageSettings(initialValues); + } + closeDialogAndClearOpenFlag(); + }; + + const onClose = ( + _evt?: object, + _reason?: "escapeKeyDown" | "backdropClick", + ): void => { + onCancel(_reason); + }; + + return ( + + + + {initialValues && ( +
+ { + if (typeof s === "string") { + setSettingsToReturnLater(s); + applyPageSettings( + JSON.parse(s) as IPageSettings, + ); + return; + } + + if (typeof s === "object" && s) { + const settings = s as IPageSettings; + setSettingsToReturnLater(settings); + applyPageSettings(settings); + return; + } + + throw new Error( + "PageSettingsDialog: unexpected value from config-r onChange", + ); + }} + > + + + + + + + + +
+ )} +
+ + + + +
+ ); +}; + +export const showPageSettingsDialog = () => { + if (!isOpenAlready) { + isOpenAlready = true; + ShowEditViewDialog(); + } +}; diff --git a/src/BloomBrowserUI/react_components/color-picking/bloomPalette.ts b/src/BloomBrowserUI/react_components/color-picking/bloomPalette.ts index 0b8e3278b01d..04b9d1e09ab4 100644 --- a/src/BloomBrowserUI/react_components/color-picking/bloomPalette.ts +++ b/src/BloomBrowserUI/react_components/color-picking/bloomPalette.ts @@ -8,6 +8,7 @@ export enum BloomPalette { BloomReaderBookshelf = "bloom-reader-bookshelf", TextBackground = "overlay-background", HighlightBackground = "highlight-background", + PageColors = "page-colors", } // This array provides a useful default palette for the color picker dialog. @@ -64,6 +65,25 @@ export const HighlightBackgroundPalette: string[] = [ "#C5F0FF", ]; +// Light background colors suitable for page backgrounds. +// (Users can still pick any color, but these are the suggested defaults.) +export const PageColorsPalette: string[] = [ + "#FFFFFF", // white + "#F7F7F7", // very light gray + "#FFF7E6", // warm cream + "#FFF1F2", // very light pink + "#FCE7F3", // pale rose + "#F3E8FF", // pale lavender + "#EDE9FE", // pale purple + "#E0F2FE", // pale sky + "#E0F7FA", // pale cyan + "#E6FFFA", // pale teal + "#ECFDF3", // pale green + "#F7FEE7", // pale lime + "#FFFBEB", // pale amber + "#FEF3C7", // light beige +]; + const specialColors: IColorInfo[] = [ // #DFB28B is the color Comical has been using as the default for captions. // It's fairly close to the "Calico" color defined at https://www.htmlcsscolor.com/hex/D5B185 (#D5B185) @@ -110,6 +130,9 @@ export async function getHexColorsForPalette( case BloomPalette.CoverBackground: factoryColors = CoverBackgroundPalette; break; + case BloomPalette.PageColors: + factoryColors = PageColorsPalette; + break; case BloomPalette.Text: factoryColors = TextColorPalette; break; @@ -156,6 +179,9 @@ export function getDefaultColorsFromPalette( case BloomPalette.CoverBackground: palette = CoverBackgroundPalette; break; + case BloomPalette.PageColors: + palette = PageColorsPalette; + break; case BloomPalette.Text: palette = TextColorPalette; break; diff --git a/src/BloomBrowserUI/react_components/color-picking/colorPickerDialog.tsx b/src/BloomBrowserUI/react_components/color-picking/colorPickerDialog.tsx index 6688187f6c7b..0cd7d2c30124 100644 --- a/src/BloomBrowserUI/react_components/color-picking/colorPickerDialog.tsx +++ b/src/BloomBrowserUI/react_components/color-picking/colorPickerDialog.tsx @@ -1,4 +1,4 @@ -import { css } from "@emotion/react"; +import { css, Global } from "@emotion/react"; import * as React from "react"; import * as ReactDOM from "react-dom"; import { useEffect, useRef, useState } from "react"; @@ -283,9 +283,30 @@ const ColorPickerDialog: React.FC = (props) => { props.onChange(color); }; + const dialogOpen = props.open === undefined ? open : props.open; + + // The MUI backdrop is rendered outside the dialog tree, so we use a body class + // to suppress it while the color picker is open. + useEffect(() => { + if (!dialogOpen) { + return; + } + document.body.classList.add("bloom-hide-color-picker-backdrop"); + return () => { + document.body.classList.remove("bloom-hide-color-picker-backdrop"); + }; + }, [dialogOpen]); + return ( + = (props) => { padding: 10px 14px 10px 10px; // maintain same spacing all around dialog content and between header/footer } `} - open={props.open === undefined ? open : props.open} + hideBackdrop={true} + BackdropProps={{ + invisible: true, + }} + slotProps={{ + backdrop: { + invisible: true, + }, + }} + open={dialogOpen} ref={dlgRef} onClose={( _event, @@ -429,6 +459,7 @@ export interface IColorDisplayButtonProps { width?: number; disabled?: boolean; onClose: (result: DialogResult, newColor: string) => void; + onChange?: (newColor: string) => void; palette: BloomPalette; } @@ -494,9 +525,13 @@ export const ColorDisplayButton: React.FC = ( props.initialColor, )} onInputFocus={() => {}} - onChange={(color: IColorInfo) => - setCurrentButtonColor(color.colors[0]) - } + onChange={(color: IColorInfo) => { + const newColor = color.colors[0]; + setCurrentButtonColor(newColor); + if (props.onChange) { + props.onChange(newColor); + } + }} /> ); diff --git a/src/BloomExe/Book/HtmlDom.cs b/src/BloomExe/Book/HtmlDom.cs index 8386e6787a8e..a53a180cbbd7 100644 --- a/src/BloomExe/Book/HtmlDom.cs +++ b/src/BloomExe/Book/HtmlDom.cs @@ -1915,6 +1915,14 @@ SafeXmlElement edittedPageDiv //html file in a browser. destinationPageDiv.SetAttribute("lang", edittedPageDiv.GetAttribute("lang")); + // Allow saving per-page CSS custom properties (e.g. --page-background-color) stored on the page div. + // If missing, remove any previously-saved style. + var style = edittedPageDiv.GetAttribute("style"); + if (string.IsNullOrEmpty(style)) + destinationPageDiv.RemoveAttribute("style"); + else + destinationPageDiv.SetAttribute("style", style); + // Copy the two background audio attributes which can be set using the music toolbox. // Ensuring that volume is missing unless the main attribute is non-empty is // currently redundant, everything should work if we just copied all attributes. diff --git a/src/BloomExe/Edit/EditingView.cs b/src/BloomExe/Edit/EditingView.cs index b315fe1a48e5..c7932243c420 100644 --- a/src/BloomExe/Edit/EditingView.cs +++ b/src/BloomExe/Edit/EditingView.cs @@ -1913,6 +1913,23 @@ public void SaveAndOpenBookSettingsDialog() ); } + public void SaveAndOpenPageSettingsDialog() + { + _model.SaveThen( + () => + { + RunJavascriptAsync("editTabBundle.showEditViewPageSettingsDialog();"); + return _model.CurrentPage.Id; + }, + () => { } // wrong state, do nothing + ); + } + + private void _pageSettingsButton_Click(object sender, EventArgs e) + { + SaveAndOpenPageSettingsDialog(); + } + // This is temporary code we added in 6.0 when trying to determine why we are sometimes losing // user data upon save. See BL-13120. private void _topBarPanel_Click(object sender, EventArgs e) diff --git a/src/BloomExe/web/controllers/EditingViewApi.cs b/src/BloomExe/web/controllers/EditingViewApi.cs index 114a27348e6b..5bd7dcfa6e89 100644 --- a/src/BloomExe/web/controllers/EditingViewApi.cs +++ b/src/BloomExe/web/controllers/EditingViewApi.cs @@ -120,6 +120,11 @@ public void RegisterWithApiHandler(BloomApiHandler apiHandler) HandleShowBookSettingsDialog, true ); + apiHandler.RegisterEndpointHandler( + "editView/showPageSettingsDialog", + HandleShowPageSettingsDialog, + true + ); } private void HandleJumpToPage(ApiRequest request) @@ -135,6 +140,12 @@ private void HandleShowBookSettingsDialog(ApiRequest request) View.SaveAndOpenBookSettingsDialog(); } + private void HandleShowPageSettingsDialog(ApiRequest request) + { + request.PostSucceeded(); + View.SaveAndOpenPageSettingsDialog(); + } + /// /// This one is for the snapping function on dragging origami splitters. /// diff --git a/src/content/appearanceMigrations/efl-zeromargin1/customBookStyles.css b/src/content/appearanceMigrations/efl-zeromargin1/customBookStyles.css index c70b168314f5..6a7f94f5558a 100644 --- a/src/content/appearanceMigrations/efl-zeromargin1/customBookStyles.css +++ b/src/content/appearanceMigrations/efl-zeromargin1/customBookStyles.css @@ -28,7 +28,7 @@ --pageNumber-color: black; --pageNumber-background-width: 17px; --pageNumber-border-radius: 50%; - --pageNumber-background-color: #ffffff; + --pageNumber-background-color: transparent; font-family: "ABeeZee"; z-index: 1000; diff --git a/src/content/appearanceThemes/appearance-theme-default.css b/src/content/appearanceThemes/appearance-theme-default.css index 532dbed270cb..f7d7274e5a36 100644 --- a/src/content/appearanceThemes/appearance-theme-default.css +++ b/src/content/appearanceThemes/appearance-theme-default.css @@ -39,6 +39,8 @@ --pageNumber-background-width: unset; /* for when we need to have a colored background, e.g. a circle */ /* background-color: value in .numberedPage:after to display the page number */ --pageNumber-background-color: transparent; + /* color: value in .numberedPage:after to display the page number */ + --pageNumber-color: black; /* border-radius: value in .numberedPage:after to display the page number */ --pageNumber-border-radius: 0px; /* left: value in .numberedPage.side-left:after to display the page number */ diff --git a/src/content/appearanceThemes/appearance-theme-rounded-border-ebook.css b/src/content/appearanceThemes/appearance-theme-rounded-border-ebook.css index 36d7d8f3cf4c..aa769b7c0a0d 100644 --- a/src/content/appearanceThemes/appearance-theme-rounded-border-ebook.css +++ b/src/content/appearanceThemes/appearance-theme-rounded-border-ebook.css @@ -26,16 +26,16 @@ .numberedPage:where([class*="Device"]:not(.bloom-interactive-page)) { --topLevel-text-padding: 0.5em; } - [class*="Device"].numberedPage:not(.bloom-interactive-page) { --pageNumber-extra-height: 0mm !important; /* we put the page number on top of the image so we don't need a margin boost */ + --pageNumber-background-color: #ffffff; /* I'm not clear why this is white, but all I did in this change is to move it so that it can be overridden by page settings */ } [class*="Device"].numberedPage:not(.bloom-interactive-page)::after { --pageNumber-bottom: var(--page-margin-bottom); --pageNumber-top: unset; --pageNumber-font-size: 11pt; --pageNumber-border-radius: 50%; - --pageNumber-background-color: #ffffff; + --pageNumber-background-width: 33px; --pageNumber-always-left-margin: var(--page-margin-left); --pageNumber-right-margin: deliberately-invalid; /* prevents right being set at all. unset does not work. Prevent centering for this layout */ diff --git a/src/content/appearanceThemes/appearance-theme-zero-margin-ebook.css b/src/content/appearanceThemes/appearance-theme-zero-margin-ebook.css index 520bf437b01c..784d6a3db242 100644 --- a/src/content/appearanceThemes/appearance-theme-zero-margin-ebook.css +++ b/src/content/appearanceThemes/appearance-theme-zero-margin-ebook.css @@ -17,8 +17,8 @@ Note that hiding the page numbers is done by a setting in appearance.json, not h --page-horizontalSplit-height: 0mm; } -/* The section below controls the page number and the white circle around it. */ -.Device16x9Landscape.numberedPage { +.numberedPage { + --pageNumber-background-color: #ffffff; /* I'm not clear why this is white, but all I did in this change is to move it so that it can be overridden by page settings */ --pageNumber-extra-height: 0mm !important; /* we put the page number on top of the image so we don't need a margin boost */ } .Device16x9Portrait.numberedPage { @@ -32,7 +32,7 @@ Note that hiding the page numbers is done by a setting in appearance.json, not h --pageNumber-font-size: 11pt; border-radius: 50%; - --pageNumber-background-color: #ffffff; + --pageNumber-background-width: 33px; --pageNumber-always-left-margin: var(--page-margin-left); --pageNumber-right-margin: deliberately-invalid; /* prevents right being set at all. unset does not work. Prevent centering for this layout */ diff --git a/src/content/bookLayout/pageNumbers.less b/src/content/bookLayout/pageNumbers.less index 441e0ab35281..e845542e69ea 100644 --- a/src/content/bookLayout/pageNumbers.less +++ b/src/content/bookLayout/pageNumbers.less @@ -7,6 +7,7 @@ // themes can override this as needed. If you have reasonable margins, you don't need to add anything to fit in a pageNumber --pageNumber-extra-height: 0mm; // must have units } + .numberedPage { &:after { content: attr(data-page-number); @@ -22,6 +23,8 @@ bottom: var(--pageNumber-bottom); top: var(--pageNumber-top); background-color: var(--pageNumber-background-color); + color: var(--pageNumber-color); + border-radius: var(--pageNumber-border-radius); z-index: 1000; // These are needed to get the number centered in a circle. They have diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000000..fb57ccd13afb --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + +