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

Desktop: Allow for custom Joplin theme and Ace editor styles (#2099)

* Delete unused file

* Implement CssUtils

* Inject custom CSS styles

* Add info about custom CSS styles to README

* Add note that ElectronClient/app/app.js is generated

* Add support for Setting.TYPE_BUTTON

* Add buttons in Preferences to open custom CSS files

* Swap custom CSS filenames

* Swap custom CSS filenames

* Wrap "Edit" with translation fn

* Incorporate PR feedback from @laurent22

* Add openOrCreateFile to Settings

* Move openOrCreateFile to shim

* Removing header for now - see https://github.com/laurent22/joplin/pull/2099#discussion_r353120915
This commit is contained in:
Devon Zuegel
2019-12-12 16:40:58 -08:00
committed by Laurent Cozic
parent 4f3e031f4f
commit 611be7c0fa
9 changed files with 120 additions and 12 deletions

View File

@@ -39,6 +39,7 @@ const BaseService = require('lib/services/BaseService');
const SearchEngine = require('lib/services/SearchEngine');
const KvStore = require('lib/services/KvStore');
const MigrationService = require('lib/services/MigrationService');
const CssUtils = require('lib/CssUtils');
SyncTargetRegistry.addClass(SyncTargetFilesystem);
SyncTargetRegistry.addClass(SyncTargetOneDrive);
@@ -609,6 +610,11 @@ class BaseApplication {
await Setting.load();
// Loads app-wide styles. (Markdown preview-specific styles loaded in app.js)
const dir = Setting.value('profileDir');
const filename = Setting.custom_css_files.JOPLIN_APP;
await CssUtils.injectCustomStyles(`${dir}/${filename}`);
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
if (Setting.value('firstStart')) {

View File

@@ -0,0 +1,27 @@
const fs = require('fs-extra');
const loadCustomCss = async filePath => {
let cssString = '';
if (await fs.pathExists(filePath)) {
try {
cssString = await fs.readFile(filePath, 'utf-8');
} catch (error) {
let msg = error.message ? error.message : '';
msg = `Could not load custom css from ${filePath}\n${msg}`;
error.message = msg;
throw error;
}
}
return cssString;
};
const injectCustomStyles = async cssFilePath => {
const css = await loadCustomCss(cssFilePath);
const styleTag = document.createElement('style');
styleTag.type = 'text/css';
styleTag.appendChild(document.createTextNode(css));
document.head.appendChild(styleTag);
};
module.exports = {loadCustomCss, injectCustomStyles};

View File

@@ -1,9 +0,0 @@
const layoutUtils = {};
layoutUtils.size = function(preferred, min, max) {
if (preferred < min) return min;
if (typeof max !== 'undefined' && preferred > max) return max;
return preferred;
};
module.exports = layoutUtils;

View File

@@ -410,6 +410,43 @@ class Setting extends BaseModel {
},
'style.sidebar.width': { value: 150, minimum: 80, maximum: 400, type: Setting.TYPE_INT, public: false, appTypes: ['desktop'] },
'style.noteList.width': { value: 150, minimum: 80, maximum: 400, type: Setting.TYPE_INT, public: false, appTypes: ['desktop'] },
// TODO: Is there a better way to do this? The goal here is to simply have
// a way to display a link to the customizable stylesheets, not for it to
// serve as a customizable Setting. But because the Setting page is auto-
// generated from this list of settings, there wasn't a really elegant way
// to do that directly in the React markup.
'style.customCss.renderedMarkdown': {
onClick: () => {
const dir = Setting.value('profileDir');
const filename = Setting.custom_css_files.RENDERED_MARKDOWN;
const filepath = `${dir}/${filename}`;
const defaultContents = '/* For styling the rendered Markdown */';
shim.openOrCreateFile(filepath, defaultContents);
},
type: Setting.TYPE_BUTTON,
public: true,
appTypes: ['desktop'],
label: () => _('Custom stylesheet for rendered Markdown'),
section: 'appearance',
},
'style.customCss.joplinApp': {
onClick: () => {
const dir = Setting.value('profileDir');
const filename = Setting.custom_css_files.JOPLIN_APP;
const filepath = `${dir}/${filename}`;
const defaultContents = `/* For styling the entire Joplin app (except the rendered Markdown, which is defined in \`${Setting.custom_css_files.RENDERED_MARKDOWN}\`) */`;
shim.openOrCreateFile(filepath, defaultContents);
},
type: Setting.TYPE_BUTTON,
public: true,
appTypes: ['desktop'],
label: () => _('Custom stylesheet for Joplin-wide app styles'),
section: 'appearance',
},
autoUpdateEnabled: { value: true, type: Setting.TYPE_BOOL, section: 'application', public: true, appTypes: ['desktop'], label: () => _('Automatically update the application') },
'autoUpdate.includePreReleases': { value: false, type: Setting.TYPE_BOOL, section: 'application', public: true, appTypes: ['desktop'], label: () => _('Get pre-releases when checking for updates'), description: () => _('See the pre-release page for more details: %s', 'https://joplinapp.org/prereleases') },
'clipperServer.autoStart': { value: false, type: Setting.TYPE_BOOL, public: false },
@@ -937,6 +974,7 @@ Setting.TYPE_STRING = 2;
Setting.TYPE_BOOL = 3;
Setting.TYPE_ARRAY = 4;
Setting.TYPE_OBJECT = 5;
Setting.TYPE_BUTTON = 6;
Setting.THEME_LIGHT = 1;
Setting.THEME_DARK = 2;
@@ -966,6 +1004,12 @@ Setting.DATE_FORMAT_6 = 'DD.MM.YYYY';
Setting.TIME_FORMAT_1 = 'HH:mm';
Setting.TIME_FORMAT_2 = 'h:mm A';
Setting.custom_css_files = {
JOPLIN_APP: 'userchrome.css',
RENDERED_MARKDOWN: 'userstyle.css',
};
// Contains constants that are set by the application and
// cannot be modified by the user:
Setting.constants_ = {

View File

@@ -358,7 +358,23 @@ function shimInit() {
shim.openUrl = url => {
const { bridge } = require('electron').remote.require('./bridge');
bridge().openExternal(url);
// Returns true if it opens the file successfully; returns false if it could
// not find the file.
return bridge().openExternal(url);
};
shim.openOrCreateFile = (filepath, defaultContents) => {
// If the file doesn't exist, create it
if (!fs.existsSync(filepath)) {
fs.writeFile(filepath, defaultContents, 'utf-8', (error) => {
if (error) {
console.error(`error: ${error}`);
}
});
}
// Open the file
return shim.openUrl(`file://${filepath}`);
};
shim.waitForFrame = () => {};

View File

@@ -190,6 +190,9 @@ shim.Buffer = null;
shim.openUrl = () => {
throw new Error('Not implemented');
};
shim.openOrCreateFile = () => {
throw new Error('Not implemented');
};
shim.waitForFrame = () => {
throw new Error('Not implemented');
};