1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-10 22:11:50 +02:00

Desktop: Resolves #12113: Allow users to change the font used in the Markdown viewer and Rich Text Editor (#12356)

This commit is contained in:
Henry Heino
2025-06-07 03:15:59 -07:00
committed by GitHub
parent 3d2ac91b8a
commit 484deb450b
9 changed files with 35 additions and 8 deletions

View File

@@ -1128,7 +1128,6 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: Ref<NoteBodyEditorRef>) => {
const allAssetsOptions: NoteStyleOptions = {
contentMaxWidthTarget: '.mce-content-body',
contentWrapperSelector: '.mce-content-body',
scrollbarSize: props.scrollbarSize,
themeId: props.contentMarkupLanguage === MarkupLanguage.Html ? 1 : null,
whiteBackgroundNoteRendering: props.whiteBackgroundNoteRendering,
};
@@ -1145,7 +1144,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: Ref<NoteBodyEditorRef>) => {
cancelled = true;
};
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [editor, props.noteId, props.themeId, props.scrollbarSize, props.markupToHtml, props.allAssets, props.content, props.resourceInfos, props.contentKey, props.contentMarkupLanguage, props.whiteBackgroundNoteRendering]);
}, [editor, props.noteId, props.themeId, props.markupToHtml, props.allAssets, props.content, props.resourceInfos, props.contentKey, props.contentMarkupLanguage, props.whiteBackgroundNoteRendering]);
useEffect(() => {
if (!editor) return () => {};

View File

@@ -157,6 +157,7 @@ function NoteEditorContent(props: NoteEditorProps) {
customCss: props.customCss,
plugins: props.plugins,
scrollbarSize: props.scrollbarSize,
baseFontFamily: props.viewerFontFamily,
});
const allAssets = useCallback(async (markupLanguage: number, options: AllAssetsOptions = null) => {
@@ -176,9 +177,10 @@ function NoteEditorContent(props: NoteEditorProps) {
contentMaxWidth: props.contentMaxWidth,
contentMaxWidthTarget: options.contentMaxWidthTarget,
scrollbarSize: props.scrollbarSize,
baseFontFamily: props.viewerFontFamily,
whiteBackgroundNoteRendering: options.whiteBackgroundNoteRendering,
});
}, [props.plugins, props.themeId, props.scrollbarSize, props.customCss, props.contentMaxWidth]);
}, [props.plugins, props.themeId, props.scrollbarSize, props.viewerFontFamily, props.customCss, props.contentMaxWidth]);
const handleProvisionalFlag = useCallback(() => {
if (props.isProvisional) {
@@ -457,6 +459,7 @@ function NoteEditorContent(props: NoteEditorProps) {
fontSize: Setting.value('style.editor.fontSize'),
contentMaxWidth: props.contentMaxWidth,
scrollbarSize: props.scrollbarSize,
baseFontFamily: props.viewerFontFamily,
isSafeMode: props.isSafeMode,
useCustomPdfViewer: props.useCustomPdfViewer,
// We need it to identify the context for which media is rendered.
@@ -712,6 +715,7 @@ const mapStateToProps = (state: AppState, ownProps: ConnectProps) => {
], whenClauseContext)[0] as ToolbarButtonInfo,
contentMaxWidth: state.settings['style.editor.contentMaxWidth'],
scrollbarSize: state.settings['style.scrollbarSize'],
viewerFontFamily: state.settings['style.viewer.fontFamily'],
tabMovesFocus: state.settings['editor.tabMovesFocus'],
isSafeMode: state.settings.isSafeMode,
useCustomPdfViewer: false,

View File

@@ -57,6 +57,7 @@ export interface NoteEditorProps {
setTagsToolbarButtonInfo: ToolbarButtonInfo;
contentMaxWidth: number;
scrollbarSize: ScrollbarSize;
viewerFontFamily: string;
isSafeMode: boolean;
useCustomPdfViewer: boolean;
shareCacheSetting: string;
@@ -131,6 +132,7 @@ export interface NoteBodyEditorProps {
plugins: PluginStates;
mathEnabled: boolean;
fontSize: number;
baseFontFamily: string;
contentMaxWidth: number;
isSafeMode: boolean;
noteId: string;

View File

@@ -31,6 +31,7 @@ interface Props {
onBack: ()=> void;
customCss: string;
scrollbarSize: ScrollbarSize;
fontFamily: string;
}
const useNoteContent = (
@@ -40,6 +41,7 @@ const useNoteContent = (
themeId: number,
customCss: string,
scrollbarSize: ScrollbarSize,
fontFamily: string,
) => {
const [note, setNote] = useState<NoteEntity>(null);
@@ -49,6 +51,7 @@ const useNoteContent = (
plugins: {},
whiteBackgroundNoteRendering: false,
scrollbarSize,
baseFontFamily: fontFamily,
});
useAsyncEffect(async (event) => {
@@ -78,7 +81,7 @@ const useNoteContent = (
return note;
};
const NoteRevisionViewerComponent: React.FC<Props> = ({ themeId, noteId, onBack, customCss, scrollbarSize }) => {
const NoteRevisionViewerComponent: React.FC<Props> = ({ themeId, noteId, onBack, customCss, scrollbarSize, fontFamily }) => {
const helpButton_onClick = useCallback(() => {}, []);
const viewerRef = useRef<NoteViewerControl|null>(null);
const revisionListRef = useRef<HTMLSelectElement|null>(null);
@@ -87,7 +90,9 @@ const NoteRevisionViewerComponent: React.FC<Props> = ({ themeId, noteId, onBack,
const [currentRevId, setCurrentRevId] = useState('');
const [restoring, setRestoring] = useState(false);
const note = useNoteContent(viewerRef, currentRevId, revisions, themeId, customCss, scrollbarSize);
const note = useNoteContent(
viewerRef, currentRevId, revisions, themeId, customCss, scrollbarSize, fontFamily,
);
const viewer_domReady = useCallback(async () => {
// this.viewerRef_.current.openDevTools();
@@ -203,6 +208,7 @@ const mapStateToProps = (state: AppState) => {
return {
themeId: state.settings.theme,
scrollbarSize: state.settings['style.scrollbarSize'],
fontFamily: state.settings['style.viewer.fontFamily'],
};
};

View File

@@ -23,10 +23,11 @@ interface HookDependencies {
plugins: PluginStates;
whiteBackgroundNoteRendering: boolean;
scrollbarSize: ScrollbarSize;
baseFontFamily: string;
}
export default function useMarkupToHtml(deps: HookDependencies) {
const { themeId, customCss, plugins, whiteBackgroundNoteRendering, scrollbarSize } = deps;
const { themeId, customCss, plugins, whiteBackgroundNoteRendering, scrollbarSize, baseFontFamily } = deps;
const resourceBaseUrl = useMemo(() => {
return `joplin-content://note-viewer/${Setting.value('resourceDir')}/`;
@@ -70,6 +71,7 @@ export default function useMarkupToHtml(deps: HookDependencies) {
settingValue: getPluginSettingValue,
whiteBackgroundNoteRendering,
scrollbarSize: scrollbarSize,
baseFontFamily,
itemIdToUrl: (id: string, urlParameters = '') => {
if (!(id in resources) || !resources[id]) {
return null;
@@ -81,5 +83,5 @@ export default function useMarkupToHtml(deps: HookDependencies) {
});
return result;
}, [themeId, markupToHtml, whiteBackgroundNoteRendering, scrollbarSize, resourceBaseUrl]);
}, [themeId, markupToHtml, baseFontFamily, whiteBackgroundNoteRendering, scrollbarSize, resourceBaseUrl]);
}

View File

@@ -1184,6 +1184,17 @@ const builtInMetadata = (Setting: typeof SettingType) => {
isGlobal: true,
subType: SettingItemSubType.MonospaceFontFamily,
},
'style.viewer.fontFamily': {
value: '',
type: SettingItemType.String,
public: true,
appTypes: [AppType.Desktop],
section: 'appearance',
label: () => _('Viewer and Rich Text Editor font family'),
storage: SettingStorage.File,
isGlobal: true,
subType: SettingItemSubType.FontFamily,
},
'style.editor.contentMaxWidth': { value: 0, type: SettingItemType.Int, public: true, storage: SettingStorage.File, isGlobal: true, appTypes: [AppType.Desktop], section: 'appearance', label: () => _('Editor maximum width'), description: () => _('Set it to 0 to make it take the complete available space. Recommended width is 600.') },

View File

@@ -644,6 +644,7 @@ export default class MdToHtml implements MarkupRenderer {
let cssStrings = noteStyle(options.theme, {
scrollbarSize: options.scrollbarSize,
baseFontFamily: options.baseFontFamily,
contentMaxWidth: options.contentMaxWidth,
});

View File

@@ -13,6 +13,7 @@ export interface Options {
contentMaxWidthTarget?: string;
contentWrapperSelector?: string;
scrollbarSize?: number;
baseFontFamily?: string;
themeId?: number;
whiteBackgroundNoteRendering?: boolean;
}
@@ -83,7 +84,7 @@ export default function(theme: any, options: Options = null) {
theme = theme ? theme : {};
const fontFamily = '\'Avenir Next\', \'Avenir\', \'Arial\', sans-serif';
const fontFamily = options.baseFontFamily || '\'Avenir Next\', \'Avenir\', \'Arial\', sans-serif';
const contentWrapperTarget = options.contentWrapperSelector ?? '#rendered-md';
const maxWidthTarget = options.contentMaxWidthTarget ? options.contentMaxWidthTarget : contentWrapperTarget;

View File

@@ -35,6 +35,7 @@ export interface FsDriver {
export interface RenderOptions {
contentMaxWidth?: number;
scrollbarSize?: number;
baseFontFamily?: string;
bodyOnly?: boolean;
splitted?: boolean;
enableLongPress?: boolean;