Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
exports.analyzeString = function analyzeString (text, browserScope, lineShift = 0, fileName, callback, options = {"contrib":null}){
const report = [];
const ast = cssTree.parse(text,{positions:true});
cssTree.walk(ast,(node) => {
if(node.type === "Declaration"){
if(node.property in bcd.css.properties){
Object.keys(browserScope).map((browser)=>{
const supportBrowser = bcd.css.properties[node.property].__compat.support[browser];
let versionAddedProp;
if(Array.isArray(supportBrowser)){
// E.g. CSS property with prefixes
versionAddedProp = supportBrowser[0].version_added;
} else if(supportBrowser) {
versionAddedProp = supportBrowser.version_added;
}
if((versionAddedProp !== null) && ((!versionAddedProp) || (versionAddedProp !== true && semver.lt(semver.coerce(browserScope[browser]), semver.coerce(versionAddedProp)) ))){
report.push({
"featureName": "Property: " + node.property,
"browser":browser,
.then(result => {
const resultRules = csstree.toPlainObject(csstree.parse(result)).children
const originalRules = csstree.toPlainObject(csstree.parse(originalCss)).children
resultRules.should.have.length.lessThan(originalRules.length)
// not be empty
})
})
.then(result => {
const resultRules = csstree.toPlainObject(csstree.parse(result)).children
const originalRules = csstree.toPlainObject(csstree.parse(originalCss)).children
resultRules.should.have.length.lessThan(originalRules.length)
// not be empty
})
})
allHrefs.forEach(href => {
while (redirectResponses[href]) {
href = redirectResponses[href];
}
if (skippedUrls.has(href)) {
// skippedUrls are URLs that for some reason was deliberately not
// downloaded. You can supply a `options.skippable` function which
// might, for some reason, skip certain URLs. But if we don't
// remember which URLs we skipped, when we later find all the
// tags to start analyze, we'd get an error here because
// we deliberately chose to now parse its CSS.
return;
}
const ast = stylesheetAsts[href];
csstree.walk(ast, {
visit: 'Rule',
enter: function(node, item, list) {
if (
this.atrule &&
csstree.keyword(this.atrule.name).basename === 'keyframes'
) {
// Don't bother inspecting rules that are inside a keyframe.
return;
}
if (!node.prelude.children) {
const cssErrorMessage = `Invalid CSS found while evaluating ${href}: "${node.prelude.value}"`;
if (options.ignoreCSSErrors) {
console.warn(cssErrorMessage);
list.remove(item);
} else {
if (POSITION_SAFE_VALUE.indexOf(name) === -1) {
special[name] = true;
}
} else if (DONT_MIX_VALUE.hasOwnProperty(realName)) {
if (DONT_MIX_VALUE[realName].test(name)) {
special[name] = true;
}
}
break;
case 'Function':
var name = node.name;
if (!vendorId) {
vendorId = resolveKeyword(name).vendor;
}
if (name === 'rect') {
// there are 2 forms of rect:
// rect(, , , ) - standart
// rect( ) – backwards compatible syntax
// only the same form values can be merged
var hasComma = node.children.some(function(node) {
return node.type === 'Operator' && node.value === ',';
});
if (!hasComma) {
name = 'rect-backward';
}
}
special[name + '()'] = true;
// filter for mediaqueries to be used or without any mediaquery
var selectorsMq = cssTools.filterByMqs(selectors, opts.useMqs);
// filter for pseudo elements to be used
var selectorsPseudo = cssTools.filterByPseudos(selectorsMq, opts.usePseudos);
// remove PseudoClass from its SimpleSelector for proper matching
cssTools.cleanPseudos(selectorsPseudo);
// stable sort selectors
var sortedSelectors = cssTools.sortSelectors(selectorsPseudo).reverse();
// apply <style> styles to matched elements
for (var selector of sortedSelectors) {
var selectorStr = csstree.translate(selector.item.data),
selectedEls = null;
try {
selectedEls = document.querySelectorAll(selectorStr);
} catch (selectError) {
if (selectError.constructor === SyntaxError) {
console.warn(
'Warning: Syntax error when trying to select \n\n' +
selectorStr +
'\n\n, skipped. Error details: ' +
selectError,
);
continue;
}
throw selectError;
}</style>
Object.keys(cleaned).forEach(url => {
// console.log('For URL', url);
const obj = cleaned[url]
const cleanedAst = csstree.fromPlainObject(obj)
const cleanedCSS = csstree.translate(cleanedAst)
console.log(cleanedCSS)
})
function prepare (cssFile, ignoreDeclarations) {
const cssContent = fs.readFileSync(cssFile, 'utf8')
let ast
try {
ast = cssTree.parse(cssContent, { filename: cssFile, positions: true })
} catch (e) {
// CssSyntaxError
console.error('CssSyntaxError: ' + e.message + ' @ ' + e.line + ':' + e.column)
throw e
}
const cssRules = []
const cssDeclarations = {} // so it is serializable to the browser
cssTree.walkRules(ast, (rule) => {
if (rule.type === 'Atrule') {
// ignore
} else if (rule.type === 'Rule') {
const converted = rule.prelude.children.map((selector) => {
rule.block.children.each(declaration => {
if (ignoreDeclarations && ignoreDeclarations.indexOf(declaration.property.toLowerCase()) >= 0) {
return // skip because it is ignored
}
// Append to a list of locations
const key = cssTree.translate(declaration)
let locs = cssDeclarations[key]
locs = locs || []
locs.push(declaration.loc)
cssDeclarations[key] = locs
})
return cssTree.translate(selector)
Object.keys(cleaned).forEach(url => {
// console.log('For URL', url);
const obj = cleaned[url]
const cleanedAst = csstree.fromPlainObject(obj)
const cleanedCSS = csstree.translate(cleanedAst)
console.log(cleanedCSS)
})
export default function finalRuleRemover (ast, propertiesToRemove) {
// remove empty rules
csstree.walk(ast, {
visit: 'Rule',
leave: (rule, item, list) => {
if (rule.block.children.isEmpty()) {
list.remove(item)
}
}
})
// remove unwanted and empty at-rules
csstree.walk(ast, {
visit: 'Atrule',
leave: (atrule, item, list) => {
const name = csstree.keyword(atrule.name).basename
/* ==@-rule handling== */
/* - Case 0 : Non nested @-rule [REMAIN]
(@charset, @import, @namespace)
*/
if (name === 'charset' || name === 'import' || name === 'namespace') {
return
}
/* Case 1: @-rule with CSS properties inside [REMAIN]
@font-face, @keyframes - keep here, but remove later in code, unless it is used.
*/
if (name === 'font-face' || name === 'keyframes' || name === 'viewport') {