1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00
joplin/packages/lib/theme.ts

388 lines
10 KiB
TypeScript
Raw Normal View History

2020-09-15 15:01:07 +02:00
import theme_light from './themes/light';
import theme_dark from './themes/dark';
import theme_dracula from './themes/dracula';
import theme_solarizedLight from './themes/solarizedLight';
import theme_solarizedDark from './themes/solarizedDark';
import theme_nord from './themes/nord';
import theme_aritimDark from './themes/aritimDark';
import theme_oledDark from './themes/oledDark';
2020-11-05 18:58:23 +02:00
import Setting from './models/Setting';
import { Theme, ThemeAppearance } from './themes/type';
2020-09-15 15:01:07 +02:00
Refactor note editor Refactor note editor using React Hooks and TypeScript and moved editor-specific code to separate files. Moved business logic into more maintainable custom hooks. Squashed commit of the following: commit f243d9bf89bdcfa1849ee26df5c0dd3e33405010 Author: Laurent Cozic <laurent@cozic.net> Date: Sat May 2 16:04:14 2020 +0100 Fixed saving issue commit 055f68d2e8b6cf6f130336c38ac2ab480887583d Author: Laurent Cozic <laurent@cozic.net> Date: Sat May 2 15:43:38 2020 +0100 Fixed HTML notes commit 99a3cf71f58d2fedcdf3001bf4110b6e8e3993da Merge: 9be85c45f2 b16ebbbf7a Author: Laurent Cozic <laurent@cozic.net> Date: Sat May 2 12:54:42 2020 +0100 Merge branch 'master' into refactor_note_text commit 9be85c45f23e5cb1ecd612b0ee631947871ada6f Author: Laurent Cozic <laurent@cozic.net> Date: Sat May 2 12:21:01 2020 +0100 Ident to space commit 848dde1869c010fe5851f493ef7287ada5f2991e Author: Laurent Cozic <laurent@cozic.net> Date: Sat May 2 11:28:50 2020 +0100 Refactor prop types commit 13c3bbe2b4f9a522ea3f8a25e7e5e7bb026dfd4f Author: Laurent Cozic <laurent@cozic.net> Date: Sat May 2 11:15:45 2020 +0100 Fixed resource loading issue commit 50cb38e3f00ef40ea8b6a468eadd66728a3ec332 Author: Laurent Cozic <laurent@cozic.net> Date: Fri May 1 23:46:58 2020 +0100 Fixed resource loading logic commit bc42ed03735f50c8394d597bb9e67312e55752fe Author: Laurent Cozic <laurent@cozic.net> Date: Fri May 1 23:08:41 2020 +0100 Various fixes commit 03c038e6d6cbde03bd474798b96c4eb120fd1647 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 29 23:22:49 2020 +0100 Fixed resource handling commit dc6c15302fac094c4e7dec5a20c9fcc4edb3d132 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 29 22:55:13 2020 +0100 Moved more code to files commit 398d5121e53df34de89b4148ef2cfd3a7bbe4feb Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 29 00:22:43 2020 +0000 More fixes commit 3ebbb80147d7d502fd955776c7fedb743400597f Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 29 00:12:44 2020 +0000 Various improvements and bug fixes commit 52a65ed3875e0709117ca93ba723e20624577d05 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Apr 28 23:51:07 2020 +0000 Move more code to sub-files commit 33ccf530fb442d7ddae0852cbab2c335efdbbf33 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Apr 28 23:25:12 2020 +0100 Moved code to sub-files commit ba3ad2cf9fcc1d7809df4afe93cd9737585a9960 Merge: 445acdab73 150ee14de6 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Apr 28 22:28:56 2020 +0100 Merge branch 'master' into refactor_note_text commit 445acdab7368345369d7f69b9becd1e77c8383dc Author: Laurent Cozic <laurent@cozic.net> Date: Tue Apr 28 19:01:41 2020 +0100 Imported more code commit 772481d3a3ac7f0b0b00e86394c0f4fd2f3a9fa7 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Apr 27 23:43:17 2020 +0000 Handle save/load state commit b3b92192ae3a1a30e3018810346cebfad47ac5e3 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Apr 27 23:11:11 2020 +0000 Clean up and added back scroll commit 7a19ecfd0cb7fef1d58ece2e024099c7e40986da Author: Laurent Cozic <laurent@cozic.net> Date: Mon Apr 27 22:29:39 2020 +0100 More refactoring commit ac388afd381eaecfa4582b3566d032c9d953c4dc Author: Laurent Cozic <laurent@cozic.net> Date: Sun Apr 26 17:07:01 2020 +0100 Restored print commit 1d2c0ed389a5398dacc584d24922c5ea0dda861a Author: Laurent Cozic <laurent@cozic.net> Date: Sun Apr 26 12:03:15 2020 +0100 Put back search commit c618cb59d43fa3bb507dbd0b757b302ecfe907b3 Author: Laurent Cozic <laurent@cozic.net> Date: Sat Apr 25 18:21:11 2020 +0100 Restore scrolling behaviour commit 324e6ea79ebafab1d2bca246ef030751147a47eb Author: Laurent Cozic <laurent@cozic.net> Date: Sat Apr 25 10:22:31 2020 +0100 Simplified saving notes commit ef089aaf2289193bf275d94c1f2785f6d88657e4 Author: Laurent Cozic <laurent@cozic.net> Date: Sat Apr 25 10:12:16 2020 +0100 More refactoring commit 61b102307d5a98d2c1502d7bf073592da21af720 Author: Laurent Cozic <laurent@cozic.net> Date: Fri Apr 24 18:04:44 2020 +0100 Added back note revisions commit 7d5e3694d0df044b8493d9114e89e2d81c9b69ad Author: Laurent Cozic <laurent@cozic.net> Date: Thu Apr 23 22:51:52 2020 +0000 More note toolbar refactoring commit a56d58e7c80d91f29afadaffaaa004f3254482f7 Author: Laurent Cozic <laurent@cozic.net> Date: Thu Apr 23 20:54:37 2020 +0100 Finished toolbar refactoring commit 6c8ef9f44f880a9569eed5c54c9c47dca2251e5e Author: Laurent Cozic <laurent@cozic.net> Date: Thu Apr 23 19:17:44 2020 +0100 More refactoring commit 7de8057158a9256e2e0dcf948081e10a6a642216 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 22 23:48:42 2020 +0100 Started refactoring commands commit 177263c85e7d17d8ddc01b583738c2ab14b3acd7 Merge: f58f1a06e0 7ceb68d835 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 22 20:26:19 2020 +0100 Merge branch 'master' into refactor_note_text commit f58f1a06e08b3cf80e2ac7a794b15f4b5caf8932 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Apr 22 20:25:43 2020 +0100 Moving Ace Editor to separate component commit a83d3a220515137985c0f334f5848c91b8539138 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Apr 20 20:33:21 2020 +0000 Cleaned up directory structure for note editor commit c6f2e609c9443bac21de5033bbedf86ac6f12cc0 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Apr 20 19:23:06 2020 +0100 Added "note" menu to move note-related items to it commit 1219465318ae5a7a2c777ae2ec15d3357e1499df Author: Laurent Cozic <laurent@cozic.net> Date: Mon Apr 20 19:05:04 2020 +0100 Moved note related toolbar to separate component
2020-05-02 17:41:07 +02:00
const Color = require('color');
const themes: Record<number, Theme> = {
2020-09-15 15:01:07 +02:00
[Setting.THEME_LIGHT]: theme_light,
[Setting.THEME_DARK]: theme_dark,
[Setting.THEME_DRACULA]: theme_dracula,
[Setting.THEME_SOLARIZED_LIGHT]: theme_solarizedLight,
[Setting.THEME_SOLARIZED_DARK]: theme_solarizedDark,
[Setting.THEME_NORD]: theme_nord,
[Setting.THEME_ARITIM_DARK]: theme_aritimDark,
[Setting.THEME_OLED_DARK]: theme_oledDark,
};
2017-11-06 22:54:58 +02:00
export function themeById(themeId: number) {
if (!themes[themeId]) throw new Error(`Invalid theme ID: ${themeId}`);
return { ...themes[themeId] };
}
const literal = <T extends string> (str: T): T => str;
// globalStyle should be used for properties that do not change across themes
// i.e. should not be used for colors
const globalStyle = (() => {
const margin = 15; // No text and no interactive component should be within this margin
const fontFamily = 'Roboto'; // 'sans-serif',
return {
fontFamily: fontFamily,
itemMarginTop: 10,
itemMarginBottom: 10,
disabledOpacity: 0.3,
buttonMinWidth: 50,
buttonMinHeight: 30,
editorFontSize: 12,
textAreaLineHeight: 17,
lineHeight: '1.6em',
headerButtonHPadding: 6,
toolbarHeight: 26,
toolbarPadding: 6,
appearance: ThemeAppearance.Light,
mainPadding: 12,
topRowHeight: 50,
editorPaddingLeft: 8,
margin: margin,
marginRight: margin,
marginLeft: margin,
marginTop: margin,
marginBottom: margin,
icon: { fontSize: 30 },
lineInput: {
fontFamily,
maxHeight: 22,
height: 22,
paddingLeft: 5,
},
headerStyle: {
fontFamily,
},
inputStyle: {
border: '1px solid',
height: 24,
maxHeight: 24,
paddingLeft: 5,
paddingRight: 5,
boxSizing: literal('border-box'),
},
containerStyle: {
overflow: literal('auto'),
overflowY: literal('auto'),
},
buttonStyle: {
// marginRight: 10,
border: '1px solid',
minHeight: 26,
minWidth: 80,
// maxWidth: 220,
paddingLeft: 12,
paddingRight: 12,
paddingTop: 6,
paddingBottom: 6,
// boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
borderRadius: 4,
},
};
})();
export function extraStyles(theme: Theme) {
const zoomRatio = 1;
2020-09-15 15:01:07 +02:00
const baseFontSize = Math.round(12 * zoomRatio);
const fontSizes = {
fontSize: baseFontSize,
toolbarIconSize: 18,
noteViewerFontSize: Math.round(baseFontSize * 1.25),
};
2020-09-15 15:01:07 +02:00
const bgColor4 = theme.backgroundColor4;
const borderColor4: string = Color(theme.color).alpha(0.3);
const iconColor = Color(theme.color).alpha(0.8);
const focusOutlineColor = theme.colorWarn;
const backgroundColor5 = theme.backgroundColor5 ?? theme.color4;
const backgroundColorHover5 = Color(backgroundColor5).darken(0.2).hex();
const backgroundColorActive5 = Color(backgroundColor5).darken(0.4).hex();
const inputStyle = {
...globalStyle.inputStyle,
color: theme.color,
backgroundColor: theme.backgroundColor,
borderColor: theme.dividerColor,
};
const containerStyle = {
...globalStyle.containerStyle,
color: theme.color,
backgroundColor: theme.backgroundColor,
};
const buttonStyle = {
...globalStyle.buttonStyle,
color: theme.color4,
backgroundColor: theme.backgroundColor4,
borderColor: borderColor4,
userSelect: literal('none'),
// cursor: 'pointer',
};
2020-09-15 15:01:07 +02:00
const tagStyle = {
fontSize: baseFontSize,
fontFamily: globalStyle.fontFamily,
2020-09-15 15:01:07 +02:00
paddingTop: 4,
paddingBottom: 4,
paddingRight: 10,
paddingLeft: 10,
backgroundColor: theme.backgroundColor3,
color: theme.color3,
display: literal('flex'),
alignItems: literal('center'),
justifyContent: literal('center'),
2020-09-15 15:01:07 +02:00
marginRight: 8,
borderRadius: 100,
borderWidth: 0,
};
const toolbarStyle = {
height: globalStyle.toolbarHeight,
minWidth: globalStyle.toolbarHeight,
display: literal('flex'),
alignItems: literal('center'),
paddingLeft: globalStyle.headerButtonHPadding,
paddingRight: globalStyle.headerButtonHPadding,
textDecoration: literal('none'),
fontFamily: globalStyle.fontFamily,
fontSize: baseFontSize,
boxSizing: literal('border-box'),
cursor: literal('default'),
justifyContent: literal('center'),
color: theme.color,
whiteSpace: literal('nowrap'),
};
const textStyle = {
fontFamily: globalStyle.fontFamily,
fontSize: baseFontSize,
lineHeight: '1.6em',
color: theme.color,
};
const textStyle2 = {
...textStyle,
color: theme.color2,
};
const textStyleMinor = { ...textStyle,
color: theme.colorFaded,
fontSize: baseFontSize * 0.8,
};
const urlStyle = {
...textStyle,
textDecoration: literal('underline'),
color: theme.urlColor,
};
const h1Style = {
...textStyle,
color: theme.color,
fontSize: textStyle.fontSize * 1.5,
fontWeight: literal('bold'),
};
const h2Style = {
...textStyle,
color: theme.color,
fontSize: textStyle.fontSize * 1.3,
fontWeight: literal('bold'),
};
return {
zoomRatio,
...fontSizes,
selectedDividerColor: Color(theme.dividerColor).darken(0.2).hex(),
iconColor,
colorFaded2: Color(theme.color2).alpha(0.5).rgb(),
colorHover2: Color(theme.color2).alpha(0.7).rgb(),
colorActive2: Color(theme.color2).alpha(0.9).rgb(),
backgroundColorHoverDim3: Color(theme.backgroundColorHover3).alpha(0.3).rgb(),
backgroundColorActive3: Color(theme.backgroundColorHover3).alpha(0.5).rgb(),
backgroundColorHover2: Color(theme.selectedColor2).alpha(0.4).rgb(),
backgroundColorHover4: Color(theme.backgroundColorHover3).alpha(0.3).rgb(),
backgroundColorActive4: Color(theme.backgroundColorHover3).alpha(0.8).rgb(),
colorHover3: theme.color3,
borderColor4,
backgroundColor4: bgColor4,
color5: theme.color5 ?? bgColor4,
backgroundColor5,
backgroundColorHover5,
backgroundColorActive5,
focusOutlineColor,
icon: {
...globalStyle.icon,
color: theme.color,
},
lineInput: {
...globalStyle.lineInput,
color: theme.color,
backgroundColor: theme.backgroundColor,
},
containerStyle,
configScreenPadding: globalStyle.mainPadding * 2,
noteListHeaderHeight: 26,
noteListHeaderBorderPadding: 4,
textStyle,
textStyle2,
textStyleMinor,
clickableTextStyle: { ...textStyle, userSelect: literal('none') },
headerStyle: {
...globalStyle.headerStyle,
color: theme.color,
backgroundColor: theme.backgroundColor,
},
h1Style,
h2Style,
urlStyle,
inputStyle,
toolbarStyle,
tagStyle,
buttonStyle,
dialogModalLayer: {
zIndex: 9999,
display: literal('flex'),
position: literal('absolute'),
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.6)',
alignItems: literal('flex-start'),
justifyContent: literal('center'),
},
controlBox: {
marginBottom: '1em',
color: 'black', // This will apply for the calendar
display: literal('flex'),
flexDirection: literal('row'),
alignItems: literal('center'),
},
controlBoxLabel: {
marginRight: '1em',
width: '10em',
display: literal('inline-block'),
fontWeight: literal('bold'),
},
controlBoxValue: {
display: literal('inline-block'),
},
dialogBox: {
backgroundColor: theme.backgroundColor,
padding: 16,
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
marginTop: 20,
maxHeight: '80%',
display: literal('flex'),
flexDirection: literal('column'),
},
buttonIconStyle: {
color: iconColor,
marginRight: 6,
},
notificationBox: {
backgroundColor: theme.warningBackgroundColor,
display: literal('flex'),
alignItems: literal('center'),
padding: 10,
fontSize: baseFontSize,
},
dialogTitle: { ...h1Style, marginBottom: '1.2em' },
dropdownList: { ...inputStyle },
colorHover: theme.color,
backgroundHover: `${theme.selectedColor2}44`,
// In general the highlighted color, used to highlight text or icons, should be the same as selectedColor2
// but some times, depending on the theme, it might be too dark or too light, so it can be
// specified directly by the theme too.
highlightedColor: theme.highlightedColor ?? theme.selectedColor2,
};
}
type ExtraStyles = ReturnType<typeof extraStyles>;
type GlobalStyle = typeof globalStyle;
export type ThemeStyle = Theme & ExtraStyles & GlobalStyle & { cacheKey: number };
2017-11-06 22:54:58 +02:00
const themeCache_: Record<string, ThemeStyle> = {};
export function themeStyle(themeId: number): ThemeStyle {
Plugins: Added support for content scripts - For now, supports Markdown-it plugins - Also fixed slow rendering of notes in some cases - Simplified how Markdown-It plugins are created and cleaned MdToHtml code commit 89576de2896c99134f25f2a2db25008514cb1315 Merge: c75aa21f 5292fc14 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:23:00 2020 +0100 Merge branch 'release-1.3' into plugin_content_scripts commit c75aa21ffdc42764d71dc9deadba7a7ef4233995 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:19:52 2020 +0100 Fixed tests commit 075187729d11a16d385b651cbf1ebb89f14935e0 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:11:53 2020 +0100 Fixed tests commit 14696b8c651e7afdaf71269bcdbadf0d58d3ef8a Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 23:27:58 2020 +0100 Fixed slow rendering of note commit 61c09f5bf856481f91b00cfe87ff05596c63d4bc Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 22:35:21 2020 +0100 Clean up commit 9f7ea7d865a990b3a21cc8c59093390d9db61653 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 20:05:31 2020 +0100 Updated doc commit 98bf3bde8d6663f2f91ff965304b4aac00bdd98b Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 19:56:34 2020 +0100 Finished converting plugins commit fe90d92e01427bd2b38200393713ea28763507a9 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 17:52:02 2020 +0100 Simplified how Markdown-It plugins are created commit 47c7b864cbb864d5df79849f27625aecf312df4b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 16:40:11 2020 +0100 Clean up rules commit d927a238bb635a4be45f9216d776f7d07cb0a584 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:29:40 2020 +0100 Fixed tests commit 388a56c5dde4c382e3ee0035791137150adaba1b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:00:47 2020 +0100 Add support for content scripts
2020-10-21 01:23:55 +02:00
if (!themeId) throw new Error('Theme must be specified');
const cacheKey = themeId;
if (themeCache_[cacheKey]) return themeCache_[cacheKey];
const output: ThemeStyle = {
cacheKey,
...globalStyle,
...themes[themeId],
// All theme are based on the light style, and just override the
// relevant properties
...extraStyles(themes[themeId]),
};
themeCache_[cacheKey] = output;
return themeCache_[cacheKey];
2017-11-06 22:54:58 +02:00
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const cachedStyles_: any = {
themeId: null,
styles: {},
};
// cacheKey must be a globally unique key, and must change whenever
// the dependencies of the style change. If the style depends only
// on the theme, a static string can be provided as a cache key.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partially refactored code from before rule was applied
type BuildStyleCallback = (style: ThemeStyle)=> any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code from before rule was applied
export function buildStyle(cacheKey: any, themeId: number, callback: BuildStyleCallback) {
cacheKey = Array.isArray(cacheKey) ? cacheKey.join('_') : cacheKey;
// We clear the cache whenever switching themes
if (cachedStyles_.themeId !== themeId) {
cachedStyles_.themeId = themeId;
cachedStyles_.styles = {};
}
if (cachedStyles_.styles[cacheKey]) return cachedStyles_.styles[cacheKey].style;
const s = callback(themeStyle(themeId));
cachedStyles_.styles[cacheKey] = {
style: s,
timestamp: Date.now(),
};
return cachedStyles_.styles[cacheKey].style;
}