mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
squire ui: show current(under cursor) font-family and font-size in the editor toolbar
This commit is contained in:
parent
99d68bc354
commit
1fcada1b07
1 changed files with 107 additions and 1 deletions
108
dev/External/SquireUI.js
vendored
108
dev/External/SquireUI.js
vendored
|
|
@ -108,7 +108,12 @@ class SquireUI
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
select: ['11px','13px','16px','20px','24px','30px'],
|
select: ['11px','13px','16px','20px','24px','30px'],
|
||||||
|
defaultValueIndex: 2,
|
||||||
cmd: s => squire.setStyle({ fontSize: s.value })
|
cmd: s => squire.setStyle({ fontSize: s.value })
|
||||||
|
// TODO: maybe consider using https://developer.mozilla.org/en-US/docs/Web/CSS/font-size#values
|
||||||
|
// example:
|
||||||
|
// select: ['xx-small', 'x-small',' small',' medium', 'large', 'x-large', 'xx-large', 'xxx-large'],
|
||||||
|
// defaultValueIndex: 3,
|
||||||
},
|
},
|
||||||
// dir: {
|
// dir: {
|
||||||
// select: [
|
// select: [
|
||||||
|
|
@ -380,18 +385,119 @@ class SquireUI
|
||||||
changes.redo.input.disabled = !state.canRedo;
|
changes.redo.input.disabled = !state.canRedo;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
actions.font.fontSize.input.selectedIndex = actions.font.fontSize.defaultValueIndex;
|
||||||
|
|
||||||
// squire.addEventListener('focus', () => shortcuts.off());
|
// squire.addEventListener('focus', () => shortcuts.off());
|
||||||
// squire.addEventListener('blur', () => shortcuts.on());
|
// squire.addEventListener('blur', () => shortcuts.on());
|
||||||
|
|
||||||
container.append(toolbar, wysiwyg, plain);
|
container.append(toolbar, wysiwyg, plain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} fontName
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
const normalizeFontName = (fontName) => fontName.trim().replace(/(^["']*|["']*$)/g, '').trim().toLowerCase();
|
||||||
|
|
||||||
|
/** @type {string[]} - lower cased array of available font families*/
|
||||||
|
const fontFamiliesLowerCase = Object.values(actions.font.fontFamily.input.options).map(option => option.value.toLowerCase());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A theme might have CSS like div.squire-wysiwyg[contenteditable="true"] {
|
||||||
|
* font-family: 'Times New Roman', Times, serif; }
|
||||||
|
* so let's find the best match squire.getRoot()'s font
|
||||||
|
* it will also help to properly handle generic font names like 'sans-serif'
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
let defaultFontFamilyIndex = 0;
|
||||||
|
const squireRootFonts = getComputedStyle(squire.getRoot()).fontFamily.split(',').map(normalizeFontName);
|
||||||
|
fontFamiliesLowerCase.some((family, index) => {
|
||||||
|
const matchFound = family.split(',').some(availableFontName => {
|
||||||
|
const normalizedFontName = normalizeFontName(availableFontName);
|
||||||
|
return squireRootFonts.some(squireFontName => squireFontName === normalizedFontName);
|
||||||
|
});
|
||||||
|
if (matchFound) {
|
||||||
|
defaultFontFamilyIndex = index;
|
||||||
|
}
|
||||||
|
return matchFound;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instead of comparing whole 'font-family' strings,
|
||||||
|
* we are going to look for individual font names, because we might be
|
||||||
|
* editing a Draft started in another email client for example
|
||||||
|
*
|
||||||
|
* @type {Object.<string,number>}
|
||||||
|
*/
|
||||||
|
const fontNamesMap = {};
|
||||||
|
/**
|
||||||
|
* @param {string} fontFamily
|
||||||
|
* @param {number} index
|
||||||
|
*/
|
||||||
|
const processFontFamilyString = (fontFamily, index) => {
|
||||||
|
fontFamily.split(',').forEach(fontName => {
|
||||||
|
const key = normalizeFontName(fontName);
|
||||||
|
if (fontNamesMap[key] === undefined) {
|
||||||
|
fontNamesMap[key] = index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// first deal with the default font family
|
||||||
|
processFontFamilyString(fontFamiliesLowerCase[defaultFontFamilyIndex], defaultFontFamilyIndex);
|
||||||
|
// and now with the rest of the font families
|
||||||
|
fontFamiliesLowerCase.forEach((fontFamily, index) => {
|
||||||
|
if (index !== defaultFontFamilyIndex) {
|
||||||
|
processFontFamilyString(fontFamily, index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
squire.addEventListener('pathChange', e => {
|
squire.addEventListener('pathChange', e => {
|
||||||
|
|
||||||
|
const squireRoot = squire.getRoot();
|
||||||
|
|
||||||
forEachObjectValue(actions, entries => {
|
forEachObjectValue(actions, entries => {
|
||||||
forEachObjectValue(entries, cfg => {
|
forEachObjectValue(entries, cfg => {
|
||||||
// cfg.matches && cfg.input.classList.toggle('active', e.element && e.element.matches(cfg.matches));
|
// cfg.matches && cfg.input.classList.toggle('active', e.element && e.element.matches(cfg.matches));
|
||||||
cfg.matches && cfg.input.classList.toggle('active', e.element && e.element.closestWithin(cfg.matches, squire.getRoot()));
|
cfg.matches && cfg.input.classList.toggle('active', e.element && e.element.closestWithin(cfg.matches, squireRoot));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (e.element) {
|
||||||
|
// try to find font-family and/or font-size and set "select" elements' values
|
||||||
|
|
||||||
|
let sizeSelectedIndex = actions.font.fontSize.defaultValueIndex;
|
||||||
|
let familySelectedIndex = defaultFontFamilyIndex;
|
||||||
|
|
||||||
|
let elm = e.element;
|
||||||
|
let familyFound = false;
|
||||||
|
let sizeFound = false;
|
||||||
|
do {
|
||||||
|
if (!familyFound && elm.style.fontFamily) {
|
||||||
|
familyFound = true;
|
||||||
|
familySelectedIndex = -1; // show empty select if we don't know the font
|
||||||
|
const fontNames = elm.style.fontFamily.split(',');
|
||||||
|
for (let i = 0; i < fontNames.length; i++) {
|
||||||
|
const index = fontNamesMap[normalizeFontName(fontNames[i])];
|
||||||
|
if (index !== undefined) {
|
||||||
|
familySelectedIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizeFound && elm.style.fontSize) {
|
||||||
|
sizeFound = true;
|
||||||
|
// -1 is ok because it will just show a black <select>
|
||||||
|
sizeSelectedIndex = actions.font.fontSize.select.indexOf(elm.style.fontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
elm = elm.parentElement;
|
||||||
|
} while ((!familyFound || !sizeFound) && elm && elm !== squireRoot);
|
||||||
|
|
||||||
|
actions.font.fontFamily.input.selectedIndex = familySelectedIndex;
|
||||||
|
actions.font.fontSize.input.selectedIndex = sizeSelectedIndex;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
squire.addEventListener('cursor', e => {
|
squire.addEventListener('cursor', e => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue