Extension presets

This commit is contained in:
benweet 2018-04-05 19:38:17 +01:00
parent 8e4279edc1
commit 12c453867f
7 changed files with 183 additions and 102 deletions

View File

@ -80,7 +80,7 @@ export default {
mounted() { mounted() {
const preElt = this.$el.querySelector('pre.markdown-highlighting'); const preElt = this.$el.querySelector('pre.markdown-highlighting');
const scrollerElt = this.$el.querySelector('.comment__text-inner'); const scrollerElt = this.$el.querySelector('.comment__text-inner');
const clEditor = cledit(preElt, scrollerElt); const clEditor = cledit(preElt, scrollerElt, true);
clEditor.init({ clEditor.init({
sectionHighlighter: section => Prism.highlight( sectionHighlighter: section => Prism.highlight(
section.text, editorSvc.prismGrammars[section.data]), section.text, editorSvc.prismGrammars[section.data]),

View File

@ -1,6 +1,6 @@
# File properties can contain metadata used ## File properties can contain metadata used
# for your publications (Wordpress, Blogger...). ## for your publications (Wordpress, Blogger...).
# For example: ## For example:
#title: My article #title: My article
#author: #author:
@ -11,53 +11,47 @@
#status: draft #status: draft
#date: YYYY-MM-DD HH:MM:SS #date: YYYY-MM-DD HH:MM:SS
# Extension configuration ## Extensions configuration
## Preset can be `default`, `commonmark` or `zero`
## Use preset `zero` to enable extensions manually.
extensions: extensions:
preset: default
# Markdown extensions ## Markdown extensions
markdown: #markdown:
abbr: true #abbr: true
breaks: true #breaks: true
deflist: true #deflist: true
del: true #del: true
fence: true #fence: true
footnote: true #footnote: true
linkify: true #linkify: true
sub: true #sub: true
sup: true #sup: true
table: true #table: true
typographer: true #typographer: true
# Enable strict CommonMark:
#abbr: false
#breaks: false
#deflist: false
#del: false
#footnote: false
#linkify: false
#sub: false
#sup: false
#table: false
#typographer: false
# Emoji extension ## Emoji extension
emoji: #emoji:
# Enable support for emojis & emoticons ## Support for emojis & emoticons
enabled: true #enabled: true
# Enable shortcuts like :) :-(
shortcuts: false
# Katex extension ## Shortcuts like :) :-(
# Render LaTeX mathematical expressions by using: ## Disabled in the default preset.
# $...$ for inline formulas #shortcuts: false
# $$...$$ for displayed formulas.
# See https://math.meta.stackexchange.com/questions/5020
katex:
enabled: true
# Mermaid extension ## Katex extension
# Convert code blocks starting with: ## Render LaTeX mathematical expressions by using:
# ```mermaid ## $...$ for inline formulas
# into diagrams and flowcharts. ## $$...$$ for displayed formulas.
# See https://mermaidjs.github.io/ ## See https://math.meta.stackexchange.com/questions/5020
mermaid: #katex:
enabled: true #enabled: true
## Mermaid extension
## Convert code blocks starting with:
## ```mermaid
## into diagrams and flowcharts.
## See https://mermaidjs.github.io/
#mermaid:
#enabled: true

View File

@ -49,7 +49,7 @@ wkhtmltopdf:
marginRight: 25 marginRight: 25
marginBottom: 25 marginBottom: 25
marginLeft: 25 marginLeft: 25
# A3, A4, Legal or Letter # `A3`, `A4`, `Legal` or `Letter`
pageSize: A4 pageSize: A4
# Options passed to pandoc # Options passed to pandoc

58
src/data/presets.js Normal file
View File

@ -0,0 +1,58 @@
const zero = {
markdown: {
abbr: false,
breaks: false,
deflist: false,
del: false,
fence: false,
footnote: false,
linkify: false,
sub: false,
sup: false,
table: false,
typographer: false,
},
emoji: {
enabled: false,
shortcuts: false,
},
katex: {
enabled: false,
},
mermaid: {
enabled: false,
},
};
export default {
zero: [zero],
commonmark: [zero, {
markdown: {
fence: true,
},
}],
default: [zero, {
markdown: {
abbr: true,
breaks: true,
deflist: true,
del: true,
fence: true,
footnote: true,
linkify: true,
sub: true,
sup: true,
table: true,
typographer: true,
},
emoji: {
enabled: true,
},
katex: {
enabled: true,
},
mermaid: {
enabled: true,
},
}],
};

View File

@ -3,7 +3,7 @@ import TurndownService from 'turndown/lib/turndown.browser.umd';
import htmlSanitizer from '../../libs/htmlSanitizer'; import htmlSanitizer from '../../libs/htmlSanitizer';
import store from '../../store'; import store from '../../store';
function cledit(contentElt, scrollEltOpt) { function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
const scrollElt = scrollEltOpt || contentElt; const scrollElt = scrollEltOpt || contentElt;
const editor = { const editor = {
$contentElt: contentElt, $contentElt: contentElt,
@ -314,25 +314,28 @@ function cledit(contentElt, scrollEltOpt) {
}, 1); }, 1);
}); });
contentElt.addEventListener('copy', (evt) => { let turndownService;
if (evt.clipboardData) { if (isMarkdown) {
evt.clipboardData.setData('text/plain', selectionMgr.getSelectedText()); contentElt.addEventListener('copy', (evt) => {
evt.preventDefault(); if (evt.clipboardData) {
} evt.clipboardData.setData('text/plain', selectionMgr.getSelectedText());
}); evt.preventDefault();
}
});
contentElt.addEventListener('cut', (evt) => { contentElt.addEventListener('cut', (evt) => {
if (evt.clipboardData) { if (evt.clipboardData) {
evt.clipboardData.setData('text/plain', selectionMgr.getSelectedText()); evt.clipboardData.setData('text/plain', selectionMgr.getSelectedText());
evt.preventDefault(); evt.preventDefault();
replace(selectionMgr.selectionStart, selectionMgr.selectionEnd, ''); replace(selectionMgr.selectionStart, selectionMgr.selectionEnd, '');
} else { } else {
undoMgr.setCurrentMode('single'); undoMgr.setCurrentMode('single');
} }
adjustCursorPosition(); adjustCursorPosition();
}); });
const turndownService = new TurndownService(store.getters['data/computedSettings'].turndown); turndownService = new TurndownService(store.getters['data/computedSettings'].turndown);
}
contentElt.addEventListener('paste', (evt) => { contentElt.addEventListener('paste', (evt) => {
undoMgr.setCurrentMode('single'); undoMgr.setCurrentMode('single');
@ -341,17 +344,19 @@ function cledit(contentElt, scrollEltOpt) {
let clipboardData = evt.clipboardData; let clipboardData = evt.clipboardData;
if (clipboardData) { if (clipboardData) {
data = clipboardData.getData('text/plain'); data = clipboardData.getData('text/plain');
try { if (turndownService) {
const html = clipboardData.getData('text/html'); try {
if (html && !clipboardData.getData('text/css')) { const html = clipboardData.getData('text/html');
const sanitizedHtml = htmlSanitizer.sanitizeHtml(html) if (html && !clipboardData.getData('text/css')) {
.replace(/ /g, ' '); // Replace non-breaking spaces with classic spaces const sanitizedHtml = htmlSanitizer.sanitizeHtml(html)
if (sanitizedHtml) { .replace(/ /g, ' '); // Replace non-breaking spaces with classic spaces
data = turndownService.turndown(sanitizedHtml); if (sanitizedHtml) {
data = turndownService.turndown(sanitizedHtml);
}
} }
} catch (e) {
// Ignore
} }
} catch (e) {
// Ignore
} }
} else { } else {
clipboardData = window.clipboardData; clipboardData = window.clipboardData;

View File

@ -114,7 +114,7 @@ function reversePatches(patches) {
export default { export default {
createClEditor(editorElt) { createClEditor(editorElt) {
this.clEditor = cledit(editorElt, editorElt.parentNode); this.clEditor = cledit(editorElt, editorElt.parentNode, true);
clEditor = this.clEditor; clEditor = this.clEditor;
clEditor.on('contentChanged', (text) => { clEditor.on('contentChanged', (text) => {
const oldContent = store.getters['content/current']; const oldContent = store.getters['content/current'];

View File

@ -1,6 +1,7 @@
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import '../libs/clunderscore'; import '../libs/clunderscore';
import defaultProperties from '../data/defaultFileProperties.yml'; import defaultPropertiesYaml from '../data/defaultFileProperties.yml';
import presets from '../data/presets';
const origin = `${location.protocol}//${location.host}`; const origin = `${location.protocol}//${location.host}`;
@ -23,9 +24,47 @@ const parseQueryParams = (params) => {
return result; return result;
}; };
// For utils.computeProperties()
const deepOverride = (obj, opt) => {
if (obj === undefined) {
return opt;
}
const objType = Object.prototype.toString.call(obj);
const optType = Object.prototype.toString.call(opt);
if (objType !== optType) {
return obj;
}
if (objType !== '[object Object]') {
return opt === undefined ? obj : opt;
}
Object.keys({
...obj,
...opt,
}).forEach((key) => {
obj[key] = deepOverride(obj[key], opt[key]);
});
return obj;
};
// For utils.addQueryParams() // For utils.addQueryParams()
const urlParser = document.createElement('a'); const urlParser = document.createElement('a');
const deepCopy = (obj) => {
if (obj == null) {
return obj;
}
return JSON.parse(JSON.stringify(obj));
};
// Build presets
Object.keys(presets).forEach((key) => {
let preset = deepCopy(presets[key][0]);
if (presets[key][1]) {
preset = deepOverride(preset, presets[key][1]);
}
presets[key] = preset;
});
export default { export default {
cleanTrashAfter: 7 * 24 * 60 * 60 * 1000, // 7 days cleanTrashAfter: 7 * 24 * 60 * 60 * 1000, // 7 days
origin, origin,
@ -65,9 +104,7 @@ export default {
sanitizeName(name) { sanitizeName(name) {
return `${name || ''}`.slice(0, 250) || 'Untitled'; return `${name || ''}`.slice(0, 250) || 'Untitled';
}, },
deepCopy(obj) { deepCopy,
return obj == null ? obj : JSON.parse(JSON.stringify(obj));
},
serializeObject(obj) { serializeObject(obj) {
return obj === undefined ? obj : JSON.stringify(obj, (key, value) => { return obj === undefined ? obj : JSON.stringify(obj, (key, value) => {
if (Object.prototype.toString.call(value) !== '[object Object]') { if (Object.prototype.toString.call(value) !== '[object Object]') {
@ -118,26 +155,13 @@ export default {
}, },
computeProperties(yamlProperties) { computeProperties(yamlProperties) {
const customProperties = yaml.safeLoad(yamlProperties); const customProperties = yaml.safeLoad(yamlProperties);
const properties = yaml.safeLoad(defaultProperties); const defaultProperties = yaml.safeLoad(defaultPropertiesYaml);
const override = (obj, opt) => { const properties = deepOverride(defaultProperties, customProperties);
const objType = Object.prototype.toString.call(obj); const preset = deepCopy(presets[properties.extensions.preset] || presets.default);
const optType = Object.prototype.toString.call(opt); const extensions = deepOverride(preset, properties.extensions);
if (obj === undefined) { extensions.preset = properties.extensions.preset;
return opt; properties.extensions = extensions;
} else if (objType !== optType) { return properties;
return obj;
} else if (objType !== '[object Object]') {
return opt === undefined ? obj : opt;
}
Object.keys({
...obj,
...opt,
}).forEach((key) => {
obj[key] = override(obj[key], opt[key]);
});
return obj;
};
return override(properties, customProperties);
}, },
randomize(value) { randomize(value) {
return Math.floor((1 + (Math.random() * 0.2)) * value); return Math.floor((1 + (Math.random() * 0.2)) * value);