Odoo18-Base/addons/html_editor/static/src/utils/fonts.js
2025-01-06 10:57:38 +07:00

99 lines
3.7 KiB
JavaScript

export const fonts = {
/**
* Retrieves all the CSS rules which match the given parser (Regex).
*
* @param {Regex} filter
* @returns {Object[]} Array of CSS rules descriptions (objects). A rule is
* defined by 3 values: 'selector', 'css' and 'names'. 'selector'
* is a string which contains the whole selector, 'css' is a string
* which contains the css properties and 'names' is an array of the
* first captured groups for each selector part. E.g.: if the
* filter is set to match .fa-* rules and capture the icon names,
* the rule:
* '.fa-alias1::before, .fa-alias2::before { hello: world; }'
* will be retrieved as
* {
* selector: '.fa-alias1::before, .fa-alias2::before',
* css: 'hello: world;',
* names: ['.fa-alias1', '.fa-alias2'],
* }
*/
cacheCssSelectors: {},
getCssSelectors: function (filter) {
if (this.cacheCssSelectors[filter]) {
return this.cacheCssSelectors[filter];
}
this.cacheCssSelectors[filter] = [];
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
var rules;
try {
// try...catch because Firefox not able to enumerate
// document.styleSheets[].cssRules[] for cross-domain
// stylesheets.
rules = sheets[i].rules || sheets[i].cssRules;
} catch {
continue;
}
if (!rules) {
continue;
}
for (var r = 0; r < rules.length; r++) {
var selectorText = rules[r].selectorText;
if (!selectorText) {
continue;
}
var selectors = selectorText.split(/\s*,\s*/);
var data = null;
for (var s = 0; s < selectors.length; s++) {
var match = selectors[s].trim().match(filter);
if (!match) {
continue;
}
if (!data) {
data = {
selector: match[0],
css: rules[r].cssText.replace(/(^.*\{\s*)|(\s*\}\s*$)/g, ""),
names: [match[1]],
};
} else {
data.selector += ", " + match[0];
data.names.push(match[1]);
}
}
if (data) {
this.cacheCssSelectors[filter].push(data);
}
}
}
return this.cacheCssSelectors[filter];
},
/**
* List of font icons to load by editor. The icons are displayed in the media
* editor and identified like font and image (can be colored, spinned, resized
* with fa classes).
* To add font, push a new object {base, parser}
*
* - base: class who appear on all fonts
* - parser: regular expression used to select all font in css stylesheets
*
* @type Array
*/
fontIcons: [{ base: "fa", parser: /\.(fa-(?:\w|-)+)::?before/i }],
computedFonts: false,
/**
* Searches the fonts described by the @see fontIcons variable.
*/
computeFonts: function () {
if (!this.computedFonts) {
var self = this;
this.fontIcons.forEach((data) => {
data.cssData = self.getCssSelectors(data.parser);
data.alias = data.cssData.map((x) => x.names).flat();
});
this.computedFonts = true;
}
},
};