update font and style handling

This commit is contained in:
jrosh 2025-05-29 15:04:16 +02:00
commit 3c19cf1d32
No known key found for this signature in database
GPG key ID: A4D68DCA6C9CCD2D
5 changed files with 87 additions and 45 deletions

View file

@ -4,6 +4,11 @@
<meta charset="UTF-8">
<link rel="icon" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preload" href="/e-inn-reader/fonts/Fast_Sans.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="/e-inn-reader/fonts/Fast_Serif.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="/e-inn-reader/fonts/Fast_Mono.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="/e-inn-reader/fonts/Fast_Sans_Dotted.ttf" as="font" type="font/ttf" crossorigin>
<title></title>
</head>
<body>

View file

@ -1,4 +1,41 @@
@import './base.css';
@import './reset.css';
@font-face {
font-family: 'Fast Sans';
src: url('/e-inn-reader/fonts/Fast_Sans.ttf') format('truetype');
font-display: swap;
}
@font-face {
font-family: 'Fast Serif';
src: url('/e-inn-reader/fonts/Fast_Serif.ttf') format('truetype');
font-display: swap;
}
@font-face {
font-family: 'Fast Mono';
src: url('/e-inn-reader/fonts/Fast_Mono.ttf') format('truetype');
font-display: swap;
}
@font-face {
font-family: 'Fast Dotted';
src: url('/e-inn-reader/fonts/Fast_Sans_Dotted.ttf') format('truetype');
font-display: swap;
}
:root {
/* User defined colors
--text-color
--background-color
--accent-color
*/
--muted-text: color-mix(in srgb, var(--text-color) 60%, transparent);
--divider-color: color-mix(in srgb, var(--text-color) 10%, transparent);
--green: #0a0;
--red: #a00;
--blue: #00c;
}
#app{
width: 100%;

View file

@ -1,16 +1,3 @@
:root {
/* custom colors
--text-color
--background-color
--accent-color
*/
--muted-text: color-mix(in srgb, var(--text-color) 60%, transparent);
--divider-color: color-mix(in srgb, var(--text-color) 10%, transparent);
--green: #0a0;
--red: #a00;
--blue: #00c;
}
/* reset.css */
* {
margin: 0;

View file

@ -46,8 +46,14 @@ export default defineComponent({
},
emits: ['update:modelValue'],
setup(props, { emit }) {
// Default font options if none provided
const defaultFonts: FontOption[] = [
// Custom Fast fonts https://github.com/Born2Root/Fast-Font
{ label: 'Fast Sans', value: '"Fast Sans", sans-serif' },
{ label: 'Fast Serif', value: '"Fast Serif", serif' },
{ label: 'Fast Mono', value: '"Fast Mono", monospace' },
{ label: 'Fast Dotted', value: '"Fast Dotted", sans-serif' },
// Standard system fonts
{ label: 'Arial', value: 'Arial, sans-serif' },
{ label: 'Times New Roman', value: 'Times New Roman, serif' },
{ label: 'Georgia', value: 'Georgia, serif' },

View file

@ -1,5 +1,5 @@
// src/composables/useStyles.ts
import { ref, watch, nextTick, computed } from 'vue';
import { ref, watch, nextTick } from 'vue';
import { type RenditionTheme, type StylesOptions } from '../types/styles';
export function useStyles(options: StylesOptions = {}) {
@ -12,16 +12,6 @@ export function useStyles(options: StylesOptions = {}) {
const stylesModalOpen = ref(false);
const rendition = ref<RenditionTheme | null>(null);
const baseUrl = computed(() => {
return import.meta.env.VITE_BASE_URL;
});
const customFonts = {
'Fast Sans': `${baseUrl}fonts/Fast_Sans.ttf`,
'Fast Serif': `${baseUrl}fonts/Fast_Serif.ttf`,
'Fast Mono': `${baseUrl}fonts/Fast_Mono.ttf`,
'Fast Dotted': `${baseUrl}fonts/Fast_Sans_Dotted.ttf`
};
// Track if hooks are registered to avoid duplicate registration
let hooksRegistered = false;
@ -63,21 +53,42 @@ export function useStyles(options: StylesOptions = {}) {
setMeta('theme-color', backgroundColor.value);
};
// Create CSS with font-face declarations for epub.js
const createFontFaceCSS = (): string => {
let fontCSS = '';
// Import stylesheets from document to iframe
const importDocumentStylesheets = (doc: Document) => {
// Skip if already imported
if (doc.querySelector('[data-imported-stylesheets]')) return;
for (const [fontName, fontUrl] of Object.entries(customFonts)) {
fontCSS += `
@font-face {
font-family: '${fontName}';
src: url('${fontUrl}') format('truetype');
font-display: swap;
}
`;
}
// Create marker to avoid duplicates
const markerStyle = doc.createElement('style');
markerStyle.setAttribute('data-imported-stylesheets', 'true');
markerStyle.textContent = '/* Stylesheets imported */';
doc.head.appendChild(markerStyle);
return fontCSS;
const mainStylesheets = Array.from(document.styleSheets);
// Check each stylesheet for font-face rules and copy them
let fontFaceCss = '';
mainStylesheets.forEach(stylesheet => {
try {
// Access rules safely (might throw error for cross-origin sheets)
const rules = stylesheet.cssRules || stylesheet.rules;
if (!rules) return;
for (let i = 0; i < rules.length; i++) {
const rule = rules[i];
if (rule.constructor.name === 'CSSFontFaceRule') {
fontFaceCss += rule.cssText + '\n';
}
}
} catch (e) {} // Silently ignore cross-origin stylesheet errors
});
if (fontFaceCss) {
const fontStyle = doc.createElement('style');
fontStyle.setAttribute('data-custom-styles', 'imported-fonts');
fontStyle.textContent = fontFaceCss;
doc.head.appendChild(fontStyle);
}
};
// Apply styles to a specific content document
@ -85,15 +96,11 @@ export function useStyles(options: StylesOptions = {}) {
const head = doc.head || doc.getElementsByTagName('head')[0];
if (!head) return;
// Remove existing custom styles to avoid duplicates
const existingStyles = head.querySelectorAll('[data-custom-styles]');
// Remove existing theme styles to avoid duplicates
const existingStyles = head.querySelectorAll('[data-custom-styles="theme"]');
existingStyles.forEach(style => style.remove());
// Create and inject font styles
const fontStyle = doc.createElement('style');
fontStyle.setAttribute('data-custom-styles', 'fonts');
fontStyle.textContent = createFontFaceCSS();
head.appendChild(fontStyle);
importDocumentStylesheets(doc);
// Create and inject theme styles
const themeStyle = doc.createElement('style');