ckeditor_font-8.x-1.x-dev/js/ckeditor5_plugins/ckeditor5-font/src/fontsize/utils.js
js/ckeditor5_plugins/ckeditor5-font/src/fontsize/utils.js
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module font/fontsize/utils
*/
import { CKEditorError } from 'ckeditor5/src/utils.js';
/**
* Normalizes and translates the {@link module:font/fontconfig~FontSizeConfig#options configuration options}
* to the {@link module:font/fontconfig~FontSizeOption} format.
*
* @param configuredOptions An array of options taken from the configuration.
*/
export function normalizeOptions(configuredOptions) {
// Convert options to objects.
return configuredOptions
.map(item => getOptionDefinition(item))
// Filter out undefined values that `getOptionDefinition` might return.
.filter((option) => option !== undefined);
}
// Default named presets map. Always create a new instance of the preset object in order to avoid modifying references.
const namedPresets = {
get tiny() {
return {
title: 'Tiny',
model: 'tiny',
view: {
name: 'span',
classes: 'text-tiny',
priority: 7
}
};
},
get small() {
return {
title: 'Small',
model: 'small',
view: {
name: 'span',
classes: 'text-small',
priority: 7
}
};
},
get big() {
return {
title: 'Big',
model: 'big',
view: {
name: 'span',
classes: 'text-big',
priority: 7
}
};
},
get huge() {
return {
title: 'Huge',
model: 'huge',
view: {
name: 'span',
classes: 'text-huge',
priority: 7
}
};
}
};
/**
* Returns an option definition either from preset or creates one from number shortcut.
* If object is passed then this method will return it without alternating it. Returns undefined for item than cannot be parsed.
*/
function getOptionDefinition(option) {
if (typeof option === 'number') {
option = String(option);
}
// Check whether passed option is a full item definition provided by user in configuration.
if (typeof option === 'object' && isFullItemDefinition(option)) {
return attachPriority(option);
}
const preset = findPreset(option);
// Item is a named preset.
if (preset) {
return attachPriority(preset);
}
// 'Default' font size. It will be used to remove the fontSize attribute.
if (option === 'default') {
return {
model: undefined,
title: 'Default'
};
}
// At this stage we probably have numerical value to generate a preset so parse it's value.
// Discard any faulty values.
if (isNumericalDefinition(option)) {
return undefined;
}
// Return font size definition from size value.
return generatePixelPreset(option);
}
/**
* Creates a predefined preset for pixel size.
* @param definition Font size in pixels.
* @returns
*/
function generatePixelPreset(definition) {
// Extend a short (numeric value) definition.
if (typeof definition === 'string') {
definition = {
title: definition,
model: `${parseFloat(definition)}px`
};
}
definition.view = {
name: 'span',
styles: {
'font-size': definition.model
}
};
return attachPriority(definition);
}
/**
* Adds the priority to the view element definition if missing. It's required due to ckeditor/ckeditor5#2291
*/
function attachPriority(definition) {
if (definition.view && typeof definition.view !== 'string' && !definition.view.priority) {
definition.view.priority = 7;
}
return definition;
}
/**
* Returns a prepared preset definition. If passed an object, a name of preset should be defined as `model` value.
*
* @param definition.model A preset name.
*/
function findPreset(definition) {
return typeof definition === 'string' ? namedPresets[definition] : namedPresets[definition.model];
}
/**
* We treat `definition` as completed if it is an object that contains `title`, `model` and `view` values.
*/
function isFullItemDefinition(definition) {
return definition.title && definition.model && definition.view;
}
function isNumericalDefinition(definition) {
let numberValue;
if (typeof definition === 'object') {
if (!definition.model) {
/**
* Provided value as an option for {@link module:font/fontsize~FontSize} seems to invalid.
*
* See valid examples described in the {@link module:font/fontconfig~FontSizeConfig#options plugin configuration}.
*
* @error font-size-invalid-definition
*/
throw new CKEditorError('font-size-invalid-definition', null, definition);
}
else {
numberValue = parseFloat(definition.model);
}
}
else {
numberValue = parseFloat(definition);
}
return isNaN(numberValue);
}
