mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-10 01:47:03 +03:00
Added feature to allow <style> in messages
This commit is contained in:
parent
aae3072209
commit
64818025e8
46 changed files with 154 additions and 6 deletions
82
dev/Common/CSS.js
Normal file
82
dev/Common/CSS.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
|
||||
export class CSS
|
||||
{
|
||||
/*
|
||||
Parses given css string, and returns css object
|
||||
keys as selectors and values are css rules
|
||||
eliminates all css comments before parsing
|
||||
|
||||
@param source css string to be parsed
|
||||
|
||||
@return object css
|
||||
*/
|
||||
parse(source) {
|
||||
|
||||
const css = [];
|
||||
|
||||
css.toString = () => css.reduce(
|
||||
(ret, tmp) =>
|
||||
ret + tmp.selector + ' {\n'
|
||||
+ (tmp.type === 'media' ? tmp.subStyles.toString() : tmp.rules)
|
||||
+ '}\n'
|
||||
,
|
||||
''
|
||||
);
|
||||
|
||||
/**
|
||||
* Given css array, parses it and then for every selector,
|
||||
* prepends namespace to prevent css collision issues
|
||||
*/
|
||||
css.applyNamespace = (namespace) => css.forEach(obj => {
|
||||
if (obj.type === 'media') {
|
||||
obj.subStyles.applyNamespace(namespace);
|
||||
} else {
|
||||
obj.selector = obj.selector.split(',').map(selector => namespace + ' ' + selector).join(',');
|
||||
}
|
||||
});
|
||||
|
||||
if (source) {
|
||||
source = source
|
||||
// strip comments
|
||||
.replace(/\/\*[\s\S]*?\*\/|<!--|-->/gi, '')
|
||||
// strip import statements
|
||||
.replace(/@import .*?;/gi , '')
|
||||
// strip keyframe statements
|
||||
.replace(/((@.*?keyframes [\s\S]*?){([\s\S]*?}\s*?)})/gi, '');
|
||||
|
||||
// unified regex to match css & media queries together
|
||||
let unified = /((\s*?(?:\/\*[\s\S]*?\*\/)?\s*?@media[\s\S]*?){([\s\S]*?)}\s*?})|(([\s\S]*?){([\s\S]*?)})/gi,
|
||||
arr;
|
||||
|
||||
while (true) {
|
||||
arr = unified.exec(source);
|
||||
if (arr === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
let selector = arr[arr[2] === undefined ? 5 : 2].split('\r\n').join('\n').trim()
|
||||
// Never have more than a single line break in a row
|
||||
.replace(/\n+/, "\n");
|
||||
|
||||
// determine the type
|
||||
if (selector.includes('@media')) {
|
||||
// we have a media query
|
||||
css.push({
|
||||
selector: selector,
|
||||
type: 'media',
|
||||
subStyles: this.parse(arr[3] + '\n}') //recursively parse media query inner css
|
||||
});
|
||||
} else if (!selector.includes('@') && ![':root','html','body'].includes(selector)) {
|
||||
// we have standard css
|
||||
css.push({
|
||||
selector: selector,
|
||||
rules: arr[6]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return css;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue