mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
allow overriding theme fonts
This commit is contained in:
parent
d5bd9875f9
commit
e6bc8ed3b5
@ -1,7 +1,31 @@
|
||||
import server from "../../services/server.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import appContext from "../../services/app_context.js";
|
||||
import libraryLoader from "../../services/library_loader.js";
|
||||
|
||||
const FONT_FAMILIES = [
|
||||
{ value: "theme", label: "Theme defined" },
|
||||
{ value: "serif", label: "Serif" },
|
||||
{ value: "sans-serif", label: "Sans Serif" },
|
||||
{ value: "monospace", label: "Monospace" },
|
||||
{ value: "Arial", label: "Arial" },
|
||||
{ value: "Verdana", label: "Verdana" },
|
||||
{ value: "Helvetica", label: "Helvetica" },
|
||||
{ value: "Tahoma", label: "Tahoma" },
|
||||
{ value: "Trebuchet MS", label: "Trebuchet MS" },
|
||||
{ value: "Times New Roman", label: "Times New Roman" },
|
||||
{ value: "Georgia", label: "Georgia" },
|
||||
{ value: "Garamond", label: "Garamond" },
|
||||
{ value: "Courier New", label: "Courier New" },
|
||||
{ value: "Brush Script MT", label: "Brush Script MT" },
|
||||
{ value: "Impact", label: "Impact" },
|
||||
{ value: "American Typewriter", label: "American Typewriter" },
|
||||
{ value: "Andalé Mono", label: "Andalé Mono" },
|
||||
{ value: "Lucida Console", label: "Lucida Console" },
|
||||
{ value: "Monaco", label: "Monaco" },
|
||||
{ value: "Bradley Hand", label: "Bradley Hand" },
|
||||
{ value: "Luminari", label: "Luminari" },
|
||||
{ value: "Comic Sans MS", label: "Comic Sans MS" },
|
||||
];
|
||||
|
||||
const TPL = `
|
||||
<p><strong>Settings on this options tab are saved automatically after each change.</strong></p>
|
||||
@ -9,10 +33,14 @@ const TPL = `
|
||||
<form>
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="theme-select">Theme</label>
|
||||
<select class="form-control" id="theme-select"></select>
|
||||
<label for="heading-style">Heading style</label>
|
||||
<select class="form-control" id="heading-style">
|
||||
<option value="plain">Plain</option>
|
||||
<option value="underline">Underline</option>
|
||||
<option value="markdown">Markdown-style</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-4">
|
||||
<label for="zoom-factor-select">Zoom factor (desktop build only)</label>
|
||||
|
||||
@ -28,71 +56,144 @@ const TPL = `
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="heading-style">Heading style</label>
|
||||
<select class="form-control" id="heading-style">
|
||||
<option value="plain">Plain</option>
|
||||
<option value="underline">Underline</option>
|
||||
<option value="markdown">Markdown-style</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<p>Zooming can be controlled with CTRL+- and CTRL+= shortcuts as well.</p>
|
||||
|
||||
<h4>Font sizes</h4>
|
||||
<h4>Theme</h4>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="main-font-size">Main font size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="main-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
<label for="theme-select">Theme</label>
|
||||
<select class="form-control" id="theme-select"></select>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-4">
|
||||
<label for="tree-font-size">Note tree font size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="tree-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<label for="detail-font-size">Note detail font size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="detail-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
<label for="override-theme-fonts">Override theme fonts</label>
|
||||
<input type="checkbox" class="form-control" id="override-theme-fonts">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Note that tree and detail font sizing is relative to the main font size setting.</p>
|
||||
<div id="overriden-font-settings">
|
||||
<h4>Fonts</h4>
|
||||
|
||||
<h5>Main font</h5>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="main-font-family">Font family</label>
|
||||
<select class="form-control" id="main-font-family"></select>
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<label for="main-font-size">Size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="main-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5>Note tree font</h5>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="tree-font-family">Font family</label>
|
||||
<select class="form-control" id="tree-font-family"></select>
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<label for="tree-font-size">Size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="tree-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5>Note detail font</h5>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="detail-font-family">Font family</label>
|
||||
<select class="form-control" id="detail-font-family"></select>
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<label for="detail-font-size">Size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="detail-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5>Monospace font</h5>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-4">
|
||||
<label for="monospace-font-family">Font family</label>
|
||||
<select class="form-control" id="monospace-font-family"></select>
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<label for="monospace-font-size">Size</label>
|
||||
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" id="monospace-font-size" min="50" max="200" step="10"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Note that tree and detail font sizing is relative to the main font size setting.</p>
|
||||
|
||||
<p>Not all listed fonts may be available on your system.</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
To apply font changes, click on
|
||||
<button class="btn btn-micro" id="reload-frontend-button">reload frontend</button>
|
||||
</p>
|
||||
</form>`;
|
||||
|
||||
export default class ApperanceOptions {
|
||||
constructor() {
|
||||
$("#options-appearance").html(TPL);
|
||||
|
||||
this.$themeSelect = $("#theme-select");
|
||||
this.$zoomFactorSelect = $("#zoom-factor-select");
|
||||
this.$nativeTitleBarSelect = $("#native-title-bar-select");
|
||||
this.$headingStyle = $("#heading-style");
|
||||
|
||||
this.$themeSelect = $("#theme-select");
|
||||
this.$overrideThemeFonts = $("#override-theme-fonts");
|
||||
|
||||
this.$overridenFontSettings = $("#overriden-font-settings");
|
||||
|
||||
this.$mainFontSize = $("#main-font-size");
|
||||
this.$mainFontFamily = $("#main-font-family");
|
||||
|
||||
this.$treeFontSize = $("#tree-font-size");
|
||||
this.$treeFontFamily = $("#tree-font-family");
|
||||
|
||||
this.$detailFontSize = $("#detail-font-size");
|
||||
this.$detailFontFamily = $("#detail-font-family");
|
||||
|
||||
this.$monospaceFontSize = $("#monospace-font-size");
|
||||
this.$monospaceFontFamily = $("#monospace-font-family");
|
||||
|
||||
$("#reload-frontend-button").on("click", () => utils.reloadFrontendApp("font changes"));
|
||||
|
||||
this.$body = $("body");
|
||||
|
||||
this.$themeSelect.on('change', async () => {
|
||||
@ -103,6 +204,14 @@ export default class ApperanceOptions {
|
||||
utils.reloadFrontendApp("theme change");
|
||||
});
|
||||
|
||||
this.$overrideThemeFonts.on('change', async () => {
|
||||
const isOverriden = this.$overrideThemeFonts.is(":checked");
|
||||
|
||||
await server.put('options/overrideThemeFonts/' + isOverriden.toString());
|
||||
|
||||
this.$overridenFontSettings.toggle(isOverriden);
|
||||
});
|
||||
|
||||
this.$zoomFactorSelect.on('change', () => { appContext.triggerCommand('setZoomFactorAndSave', {zoomFactor: this.$zoomFactorSelect.val()}); });
|
||||
|
||||
this.$nativeTitleBarSelect.on('change', () => {
|
||||
@ -119,23 +228,16 @@ export default class ApperanceOptions {
|
||||
server.put('options/headingStyle/' + newHeadingStyle);
|
||||
});
|
||||
|
||||
this.$mainFontSize.on('change', async () => {
|
||||
await server.put('options/mainFontSize/' + this.$mainFontSize.val());
|
||||
const optionsToSave = [
|
||||
'mainFontFamily', 'mainFontSize',
|
||||
'treeFontFamily', 'treeFontSize',
|
||||
'detailFontFamily', 'detailFontSize',
|
||||
'monospaceFontFamily', 'monospaceFontSize'
|
||||
];
|
||||
|
||||
this.applyFontSizes();
|
||||
});
|
||||
|
||||
this.$treeFontSize.on('change', async () => {
|
||||
await server.put('options/treeFontSize/' + this.$treeFontSize.val());
|
||||
|
||||
this.applyFontSizes();
|
||||
});
|
||||
|
||||
this.$detailFontSize.on('change', async () => {
|
||||
await server.put('options/detailFontSize/' + this.$detailFontSize.val());
|
||||
|
||||
this.applyFontSizes();
|
||||
});
|
||||
for (const optionName of optionsToSave) {
|
||||
this['$' + optionName].on('change', () => server.put(`options/${optionName}/${this['$' + optionName].val()}`));
|
||||
}
|
||||
}
|
||||
|
||||
toggleBodyClass(prefix, value) {
|
||||
@ -149,6 +251,17 @@ export default class ApperanceOptions {
|
||||
}
|
||||
|
||||
async optionsLoaded(options) {
|
||||
if (utils.isElectron()) {
|
||||
this.$zoomFactorSelect.val(options.zoomFactor);
|
||||
}
|
||||
else {
|
||||
this.$zoomFactorSelect.prop('disabled', true);
|
||||
}
|
||||
|
||||
this.$nativeTitleBarSelect.val(options.nativeTitleBarVisible === 'true' ? 'show' : 'hide');
|
||||
|
||||
this.$headingStyle.val(options.headingStyle);
|
||||
|
||||
const themes = [
|
||||
{ val: 'white', title: 'White' },
|
||||
{ val: 'dark', title: 'Dark' }
|
||||
@ -165,25 +278,32 @@ export default class ApperanceOptions {
|
||||
|
||||
this.$themeSelect.val(options.theme);
|
||||
|
||||
if (utils.isElectron()) {
|
||||
this.$zoomFactorSelect.val(options.zoomFactor);
|
||||
}
|
||||
else {
|
||||
this.$zoomFactorSelect.prop('disabled', true);
|
||||
}
|
||||
|
||||
this.$nativeTitleBarSelect.val(options.nativeTitleBarVisible === 'true' ? 'show' : 'hide');
|
||||
|
||||
this.$headingStyle.val(options.headingStyle);
|
||||
this.$overrideThemeFonts.prop('checked', options.overrideThemeFonts);
|
||||
this.$overridenFontSettings.toggle(options.overrideThemeFonts === 'true');
|
||||
|
||||
this.$mainFontSize.val(options.mainFontSize);
|
||||
this.fillFontFamilyOptions(this.$mainFontFamily, options.mainFontFamily);
|
||||
|
||||
this.$treeFontSize.val(options.treeFontSize);
|
||||
this.fillFontFamilyOptions(this.$treeFontFamily, options.treeFontFamily);
|
||||
|
||||
this.$detailFontSize.val(options.detailFontSize);
|
||||
this.fillFontFamilyOptions(this.$detailFontFamily, options.detailFontFamily);
|
||||
|
||||
console.log(options);
|
||||
|
||||
this.$monospaceFontSize.val(options.monospaceFontSize);
|
||||
this.fillFontFamilyOptions(this.$monospaceFontFamily, options.monospaceFontFamily);
|
||||
}
|
||||
|
||||
applyFontSizes() {
|
||||
this.$body.get(0).style.setProperty("--main-font-size", this.$mainFontSize.val() + "%");
|
||||
this.$body.get(0).style.setProperty("--tree-font-size", this.$treeFontSize.val() + "%");
|
||||
this.$body.get(0).style.setProperty("--detail-font-size", this.$detailFontSize.val() + "%");
|
||||
fillFontFamilyOptions($select, currentValue) {
|
||||
$select.empty();
|
||||
|
||||
for (const {value, label} of FONT_FAMILIES) {
|
||||
$select.append($("<option>")
|
||||
.attr("value", value)
|
||||
.prop("selected", value === currentValue)
|
||||
.text(label));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ const TPL = `
|
||||
<div class="note-detail-editable-text note-detail-printable">
|
||||
<style>
|
||||
.note-detail-editable-text {
|
||||
font-family: var(--detail-text-font-family);
|
||||
font-family: var(--detail-font-family);
|
||||
padding-left: 14px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ const TPL = `
|
||||
.note-detail-readonly-text {
|
||||
padding-left: 24px;
|
||||
padding-top: 10px;
|
||||
font-family: var(--detail-text-font-family);
|
||||
font-family: var(--detail-font-family);
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ table td, table th {
|
||||
}
|
||||
|
||||
code, kbd, pre, samp {
|
||||
font-family: var(--font-family-monospace);
|
||||
font-family: var(--monospace-font-family);
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
@ -227,7 +227,7 @@ div.ui-tooltip {
|
||||
}
|
||||
|
||||
.CodeMirror * {
|
||||
font-family: var(--font-family-monospace) !important;
|
||||
font-family: var(--monospace-font-family) !important;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
|
@ -8,8 +8,8 @@
|
||||
--detail-font-family: MontserratLight;
|
||||
--detail-font-size: normal;
|
||||
|
||||
--font-family-monospace: JetBrainsLight;
|
||||
--detail-text-font-family: MontserratLight;
|
||||
--monospace-font-family: JetBrainsLight;
|
||||
--monospace-font-size: normal;
|
||||
|
||||
--main-background-color: #333;
|
||||
--main-text-color: #ccc;
|
||||
|
@ -11,8 +11,8 @@ html {
|
||||
--detail-font-family: MontserratLight;
|
||||
--detail-font-size: normal;
|
||||
|
||||
--font-family-monospace: JetBrainsLight;
|
||||
--detail-text-font-family: MontserratLight;
|
||||
--monospace-font-family: JetBrainsLight;
|
||||
--monospace-font-size: normal;
|
||||
|
||||
--main-background-color: white;
|
||||
--main-text-color: black;
|
||||
|
33
src/routes/api/fonts.js
Normal file
33
src/routes/api/fonts.js
Normal file
@ -0,0 +1,33 @@
|
||||
const optionService = require('../../services/options');
|
||||
|
||||
function getFontCss(req, res) {
|
||||
res.setHeader('Content-Type', 'text/css');
|
||||
|
||||
if (!optionService.getOptionBool('overrideThemeFonts')) {
|
||||
res.send('');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const optionsMap = optionService.getOptionsMap();
|
||||
|
||||
// using body to be more specific than themes' :root
|
||||
res.send(`
|
||||
body {
|
||||
--main-font-family: ${optionsMap.mainFontFamily};
|
||||
--main-font-size: ${optionsMap.mainFontSize}%;
|
||||
|
||||
--tree-font-family: ${optionsMap.treeFontFamily};
|
||||
--tree-font-size: ${optionsMap.treeFontSize}%;
|
||||
|
||||
--detail-font-family: ${optionsMap.detailFontFamily};
|
||||
--detail-font-size: ${optionsMap.detailFontSize}%;
|
||||
|
||||
--monospace-font-family: ${optionsMap.monospaceFontFamily};
|
||||
--monospace-font-size: ${optionsMap.monospaceFontSize};
|
||||
}`);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getFontCss
|
||||
};
|
@ -17,8 +17,13 @@ const ALLOWED_OPTIONS = new Set([
|
||||
'syncProxy',
|
||||
'hoistedNoteId',
|
||||
'mainFontSize',
|
||||
'mainFontFamily',
|
||||
'treeFontSize',
|
||||
'treeFontFamily',
|
||||
'detailFontSize',
|
||||
'detailFontFamily',
|
||||
'monospaceFontSize',
|
||||
'monospaceFontFamily',
|
||||
'openTabs',
|
||||
'noteInfoWidget',
|
||||
'attributesWidget',
|
||||
@ -44,7 +49,8 @@ const ALLOWED_OPTIONS = new Set([
|
||||
'headingStyle',
|
||||
'autoCollapseNoteTree',
|
||||
'autoReadonlySizeText',
|
||||
'autoReadonlySizeCode'
|
||||
'autoReadonlySizeCode',
|
||||
'overrideThemeFonts'
|
||||
]);
|
||||
|
||||
function getOptions() {
|
||||
|
@ -38,6 +38,7 @@ const similarNotesRoute = require('./api/similar_notes');
|
||||
const keysRoute = require('./api/keys');
|
||||
const backendLogRoute = require('./api/backend_log');
|
||||
const statsRoute = require('./api/stats');
|
||||
const fontsRoute = require('./api/fonts');
|
||||
|
||||
const log = require('../services/log');
|
||||
const express = require('express');
|
||||
@ -326,6 +327,8 @@ function register(app) {
|
||||
|
||||
apiRoute(POST, '/api/delete-notes-preview', notesApiRoute.getDeleteNotesPreview);
|
||||
|
||||
route(GET, '/api/fonts', [auth.checkApiAuthOrElectron], fontsRoute.getFontCss);
|
||||
|
||||
app.use('', router);
|
||||
}
|
||||
|
||||
|
@ -56,17 +56,15 @@ const defaultOptions = [
|
||||
{ name: 'noteRevisionSnapshotTimeInterval', value: '600', isSynced: true },
|
||||
{ name: 'protectedSessionTimeout', value: '600', isSynced: true },
|
||||
{ name: 'zoomFactor', value: '1.0', isSynced: false },
|
||||
{ name: 'overrideThemeFont', value: 'false', isSynced: false },
|
||||
{ name: 'mainFontFamily', value: 'sans-serif', isSynced: false },
|
||||
{ name: 'mainFontSize', value: '100', isSynced: false },
|
||||
{ name: 'treeFontFamily', value: 'sans-serif', isSynced: false },
|
||||
{ name: 'treeFontSize', value: '100', isSynced: false },
|
||||
{ name: 'detailFontFamily', value: 'sans-serif', isSynced: false },
|
||||
{ name: 'detailFontSize', value: '110', isSynced: false },
|
||||
{ name: 'calendarWidget', value: '{"enabled":true,"expanded":true,"position":20}', isSynced: false },
|
||||
{ name: 'editedNotesWidget', value: '{"enabled":true,"expanded":true,"position":50}', isSynced: false },
|
||||
{ name: 'noteInfoWidget', value: '{"enabled":true,"expanded":true,"position":100}', isSynced: false },
|
||||
{ name: 'attributesWidget', value: '{"enabled":true,"expanded":true,"position":200}', isSynced: false },
|
||||
{ name: 'linkMapWidget', value: '{"enabled":true,"expanded":true,"position":300}', isSynced: false },
|
||||
{ name: 'noteRevisionsWidget', value: '{"enabled":true,"expanded":true,"position":400}', isSynced: false },
|
||||
{ name: 'whatLinksHereWidget', value: '{"enabled":false,"expanded":true,"position":500}', isSynced: false },
|
||||
{ name: 'similarNotesWidget', value: '{"enabled":true,"expanded":true,"position":600}', isSynced: false },
|
||||
{ name: 'monospaceFontFamily', value: 'monospace', isSynced: false },
|
||||
{ name: 'monospaceFontSize', value: '110', isSynced: false },
|
||||
{ name: 'spellCheckEnabled', value: 'true', isSynced: false },
|
||||
{ name: 'spellCheckLanguageCode', value: 'en-US', isSynced: false },
|
||||
{ name: 'imageMaxWidthHeight', value: '1200', isSynced: true },
|
||||
|
@ -88,7 +88,8 @@ async function createMainWindow() {
|
||||
const parsedUrl = url.parse(targetUrl);
|
||||
|
||||
// we still need to allow internal redirects from setup and migration pages
|
||||
if (!['localhost', '127.0.0.1'].includes(parsedUrl.hostname) || (parsedUrl.path && parsedUrl.path !== '/')) {
|
||||
if (!['localhost', '127.0.0.1'].includes(parsedUrl.hostname) || (parsedUrl.path && parsedUrl.path !== '/' && parsedUrl.path !== '/?')) {
|
||||
|
||||
ev.preventDefault();
|
||||
}
|
||||
});
|
||||
|
@ -5,7 +5,7 @@
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<title>Trilium Notes</title>
|
||||
</head>
|
||||
<body class="desktop heading-style-<%= headingStyle %>" style="--main-font-size: <%= mainFontSize %>%; --tree-font-size: <%= treeFontSize %>%; --detail-font-size: <%= detailFontSize %>%;">
|
||||
<body class="desktop heading-style-<%= headingStyle %>">
|
||||
<noscript>Trilium requires JavaScript to be enabled.</noscript>
|
||||
|
||||
<script>
|
||||
@ -79,6 +79,7 @@
|
||||
<script src="libraries/split.min.js"></script>
|
||||
|
||||
<link href="stylesheets/ckeditor-theme.css" rel="stylesheet">
|
||||
<link href="api/fonts" rel="stylesheet">
|
||||
<link href="stylesheets/theme-light.css" rel="stylesheet">
|
||||
|
||||
<% if (themeCssUrl) { %>
|
||||
|
@ -131,6 +131,7 @@
|
||||
|
||||
<script src="app/mobile.js" crossorigin type="module"></script>
|
||||
|
||||
<link href="api/fonts" rel="stylesheet">
|
||||
<link href="stylesheets/ckeditor-theme.css" rel="stylesheet">
|
||||
<% if (themeCssUrl) { %>
|
||||
<link href="<%= themeCssUrl %>" rel="stylesheet">
|
||||
|
Loading…
x
Reference in New Issue
Block a user