New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

checkcss

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

checkcss - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

test/test.js

4

dist/index.d.ts

@@ -0,3 +1,5 @@

export declare const CLASS_IDENT_REGEX: RegExp;
export declare function ignoreCSS(re: RegExp | undefined): void;
export declare function extractClasses(sel: string): string[];
export declare function monitorCSS(): void;
export default function checkCSS(): Set<any> | undefined;
export default function checkCSS(): void;

@@ -0,1 +1,4 @@

// Regex for identifying class names in CSS selectors
// REF: https://www.w3.org/TR/selectors-3/#lex
export const CLASS_IDENT_REGEX = /\.-?(?:[_a-z]|[^\0-\x7f]|\\[0-9a-f]{1,6}\s?|\\[^\s0-9a-f])(?:[_a-z0-9-]|[^\0-\x7f]|\\[0-9a-f]{1,6}\s?|\\[^\s0-9a-f])*/gi;
const seen = new Set();

@@ -10,5 +13,2 @@ let defined;

for (const cl of node.classList) {
// Ignore if matches the ignore regex
if (ignoreRE?.test(cl))
continue;
// Ignore defined and already-seen classes

@@ -19,2 +19,5 @@ if (defined.has(cl) || seen.has(cl))

seen.add(cl);
// Ignore classes that mathc the ignore regex
if (ignoreRE?.test(cl))
continue;
console.warn(`Undefined CSS class: ${cl}`, node);

@@ -29,24 +32,34 @@ }

}
function isGroupingRule(rule) {
return 'cssRules' in rule;
}
function isCSSStyleRule(rule) {
return 'selectorText' in rule;
}
export function extractClasses(sel) {
const classnames = sel.match(CLASS_IDENT_REGEX) ?? [];
return classnames.map(c => {
// Strip '.'
c = c.substring(1);
// Unescape numeric escape sequences (\###)
c = c.replaceAll(/\\[0-9a-f]{1,6}\s?/gi, escape => {
return String.fromCodePoint(parseInt(escape.substring(1), 16));
});
// Unescape character escape sequences (\[some char])
c = c.replaceAll(/\\[^\s0-9a-f]/g, c => c.substring(1));
return c;
});
}
function ingestRules(rules) {
for (const rule of rules) {
if (!rule)
continue;
try {
rule.cssRules;
}
catch (err) {
console.log(`Unable to access ${rule.href}`);
continue;
}
if (rule?.cssRules) {
// Rules can contain sub-rules (e.g. @media, @print)
if (isGroupingRule(rule)) {
// Some rules are groups of rules (e.g. CSSMediaRule), so we need to
// recurse into them
ingestRules(rule.cssRules);
}
else if (rule.selectorText) {
// Get defined classes. (Regex here could probably use improvement)
const classes = rule.selectorText?.match(/\.[\w-]+/g);
if (classes) {
for (const cl of classes) {
defined.add(cl.substr(1));
}
else if (isCSSStyleRule(rule)) {
// Add each classname to the defined set
for (const classname of extractClasses(rule.selectorText)) {
console.log('INGESTING', classname);
defined.add(classname);
}

@@ -82,3 +95,3 @@ }

childList: true,
subtree: true
subtree: true,
});

@@ -88,6 +101,8 @@ }

if (defined)
return defined;
return;
defined = new Set();
// Cache
ingestRules(document.styleSheets);
// Ingest rules from all stylesheets
for (const sheet of document.styleSheets) {
ingestRules(sheet.cssRules);
}
// Do a sweep of the existing DOM

@@ -94,0 +109,0 @@ checkClassNames(document.documentElement, true);

{
"name": "checkcss",
"version": "1.2.0",
"version": "1.3.0",
"type": "module",

@@ -9,3 +9,3 @@ "description": "Utility method for warning when elements have a `class` attribute that refers to an undefined CSS class",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "node test/test.js",
"prepare": "rm -fr dist && yarn build",

@@ -12,0 +12,0 @@ "build": "tsc",

@@ -0,1 +1,6 @@

// Regex for identifying class names in CSS selectors
// REF: https://www.w3.org/TR/selectors-3/#lex
export const CLASS_IDENT_REGEX =
/\.-?(?:[_a-z]|[^\0-\x7f]|\\[0-9a-f]{1,6}\s?|\\[^\s0-9a-f])(?:[_a-z0-9-]|[^\0-\x7f]|\\[0-9a-f]{1,6}\s?|\\[^\s0-9a-f])*/gi;
const seen = new Set();

@@ -10,12 +15,13 @@ let defined: Set<any>;

function checkClassNames(node: Element, includeChildren = false) {
if (node?.classList) {
if (node?.classList) {
for (const cl of node.classList) {
// Ignore if matches the ignore regex
if (ignoreRE?.test(cl)) continue;
// Ignore defined and already-seen classes
if (defined.has(cl) || seen.has(cl)) continue;
// Mark as seen
seen.add(cl);
// Ignore classes that mathc the ignore regex
if (ignoreRE?.test(cl)) continue;
console.warn(`Undefined CSS class: ${cl}`, node);

@@ -32,19 +38,38 @@ }

function ingestRules(rules: CSSRuleList | StyleSheetList) {
function isGroupingRule(rule: CSSRule): rule is CSSGroupingRule {
return 'cssRules' in rule;
}
function isCSSStyleRule(rule: CSSRule): rule is CSSStyleRule {
return 'selectorText' in rule;
}
export function extractClasses(sel: string) {
const classnames = sel.match(CLASS_IDENT_REGEX) ?? [];
return classnames.map(c => {
// Strip '.'
c = c.substring(1);
// Unescape numeric escape sequences (\###)
c = c.replaceAll(/\\[0-9a-f]{1,6}\s?/gi, escape => {
return String.fromCodePoint(parseInt(escape.substring(1), 16));
});
// Unescape character escape sequences (\[some char])
c = c.replaceAll(/\\[^\s0-9a-f]/g, c => c.substring(1));
return c;
});
}
function ingestRules(rules: CSSRuleList) {
for (const rule of rules) {
if (!rule) continue;
try {
(rule as CSSStyleSheet).cssRules;
} catch (err) {
console.log(`Unable to access ${(rule as CSSStyleSheet).href}`);
continue;
}
if ((rule as CSSStyleSheet)?.cssRules) {
// Rules can contain sub-rules (e.g. @media, @print)
ingestRules((rule as CSSStyleSheet).cssRules);
} else if ((rule as CSSStyleRule).selectorText) {
// Get defined classes. (Regex here could probably use improvement)
const classes = (rule as CSSStyleRule).selectorText?.match(/\.[\w-]+/g);
if (classes) {
for (const cl of classes) { defined.add(cl.substr(1)); }
if (isGroupingRule(rule)) {
// Some rules are groups of rules (e.g. CSSMediaRule), so we need to
// recurse into them
ingestRules(rule.cssRules);
} else if (isCSSStyleRule(rule)) {
// Add each classname to the defined set
for (const classname of extractClasses(rule.selectorText)) {
console.log('INGESTING', classname);
defined.add(classname);
}

@@ -80,3 +105,3 @@ }

childList: true,
subtree: true
subtree: true,
});

@@ -86,7 +111,9 @@ }

export default function checkCSS() {
if (defined) return defined;
if (defined) return;
defined = new Set();
// Cache
ingestRules(document.styleSheets);
// Ingest rules from all stylesheets
for (const sheet of document.styleSheets) {
ingestRules(sheet.cssRules);
}

@@ -93,0 +120,0 @@ // Do a sweep of the existing DOM

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc