update font and style handling
This commit is contained in:
parent
25c7b9c986
commit
3c19cf1d32
5 changed files with 87 additions and 45 deletions
|
|
@ -4,6 +4,11 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.png">
|
<link rel="icon" href="/favicon.png">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<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>
|
<title></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -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{
|
#app{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
/* reset.css */
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
@ -46,8 +46,14 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue'],
|
emits: ['update:modelValue'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
// Default font options if none provided
|
|
||||||
const defaultFonts: FontOption[] = [
|
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: 'Arial', value: 'Arial, sans-serif' },
|
||||||
{ label: 'Times New Roman', value: 'Times New Roman, serif' },
|
{ label: 'Times New Roman', value: 'Times New Roman, serif' },
|
||||||
{ label: 'Georgia', value: 'Georgia, serif' },
|
{ label: 'Georgia', value: 'Georgia, serif' },
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// src/composables/useStyles.ts
|
// 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';
|
import { type RenditionTheme, type StylesOptions } from '../types/styles';
|
||||||
|
|
||||||
export function useStyles(options: StylesOptions = {}) {
|
export function useStyles(options: StylesOptions = {}) {
|
||||||
|
|
@ -12,16 +12,6 @@ export function useStyles(options: StylesOptions = {}) {
|
||||||
const stylesModalOpen = ref(false);
|
const stylesModalOpen = ref(false);
|
||||||
const rendition = ref<RenditionTheme | null>(null);
|
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
|
// Track if hooks are registered to avoid duplicate registration
|
||||||
let hooksRegistered = false;
|
let hooksRegistered = false;
|
||||||
|
|
||||||
|
|
@ -63,21 +53,42 @@ export function useStyles(options: StylesOptions = {}) {
|
||||||
setMeta('theme-color', backgroundColor.value);
|
setMeta('theme-color', backgroundColor.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create CSS with font-face declarations for epub.js
|
// Import stylesheets from document to iframe
|
||||||
const createFontFaceCSS = (): string => {
|
const importDocumentStylesheets = (doc: Document) => {
|
||||||
let fontCSS = '';
|
// Skip if already imported
|
||||||
|
if (doc.querySelector('[data-imported-stylesheets]')) return;
|
||||||
|
|
||||||
for (const [fontName, fontUrl] of Object.entries(customFonts)) {
|
// Create marker to avoid duplicates
|
||||||
fontCSS += `
|
const markerStyle = doc.createElement('style');
|
||||||
@font-face {
|
markerStyle.setAttribute('data-imported-stylesheets', 'true');
|
||||||
font-family: '${fontName}';
|
markerStyle.textContent = '/* Stylesheets imported */';
|
||||||
src: url('${fontUrl}') format('truetype');
|
doc.head.appendChild(markerStyle);
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// Apply styles to a specific content document
|
||||||
|
|
@ -85,15 +96,11 @@ export function useStyles(options: StylesOptions = {}) {
|
||||||
const head = doc.head || doc.getElementsByTagName('head')[0];
|
const head = doc.head || doc.getElementsByTagName('head')[0];
|
||||||
if (!head) return;
|
if (!head) return;
|
||||||
|
|
||||||
// Remove existing custom styles to avoid duplicates
|
// Remove existing theme styles to avoid duplicates
|
||||||
const existingStyles = head.querySelectorAll('[data-custom-styles]');
|
const existingStyles = head.querySelectorAll('[data-custom-styles="theme"]');
|
||||||
existingStyles.forEach(style => style.remove());
|
existingStyles.forEach(style => style.remove());
|
||||||
|
|
||||||
// Create and inject font styles
|
importDocumentStylesheets(doc);
|
||||||
const fontStyle = doc.createElement('style');
|
|
||||||
fontStyle.setAttribute('data-custom-styles', 'fonts');
|
|
||||||
fontStyle.textContent = createFontFaceCSS();
|
|
||||||
head.appendChild(fontStyle);
|
|
||||||
|
|
||||||
// Create and inject theme styles
|
// Create and inject theme styles
|
||||||
const themeStyle = doc.createElement('style');
|
const themeStyle = doc.createElement('style');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue