@opensourceframework/critters
Advanced tools
+10
-0
| # @opensourceframework/critters Changelog | ||
| ## 2.0.1 | ||
| ### Patch Changes | ||
| - Modernization and stabilization fixes: | ||
| - Standardized scripts and CI/CD lockfiles | ||
| - Fixed lint rules and CI/CD unblocking | ||
| - Added llms.txt for AI-First Discovery | ||
| - Include llms.txt in published files | ||
| ## 2.0.0 | ||
@@ -4,0 +14,0 @@ |
+28
-2
@@ -21,3 +21,11 @@ 'use strict'; | ||
| // src/index.js | ||
| /** | ||
| * @opensourceframework/critters | ||
| * Critical CSS inliner | ||
| * | ||
| * @original-author The Chromium Authors | ||
| * @original-repo https://github.com/GoogleChromeLabs/critters | ||
| * @license Apache-2.0 | ||
| */ | ||
| var classCache = null; | ||
@@ -421,3 +429,16 @@ var idCache = null; | ||
| function isSubpath(basePath, currentPath) { | ||
| return !path__default.default.relative(basePath, currentPath).startsWith(".."); | ||
| try { | ||
| const resolvedBase = path__default.default.resolve(basePath); | ||
| const resolvedCurrent = path__default.default.resolve(currentPath); | ||
| if (fs.existsSync(resolvedBase) && fs.existsSync(resolvedCurrent)) { | ||
| const realBase = fs.realpathSync(resolvedBase); | ||
| const realCurrent = fs.realpathSync(resolvedCurrent); | ||
| const relative2 = path__default.default.relative(realBase, realCurrent); | ||
| return !relative2.startsWith("..") && !path__default.default.isAbsolute(relative2); | ||
| } | ||
| const relative = path__default.default.relative(resolvedBase, resolvedCurrent); | ||
| return !relative.startsWith("..") && !path__default.default.isAbsolute(relative); | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
@@ -628,2 +649,7 @@ | ||
| setupLinkPreload(link, href, media, style, document, preloadMode) { | ||
| if (preloadMode === "media" || preloadMode === "swap" || preloadMode === "swap-high") { | ||
| this.logger.warn( | ||
| `CSP Warning: The '${preloadMode}' preload strategy injects inline onload event handlers which may be blocked by Content Security Policy (CSP) directives. Consider using 'preload: "js"' or 'preload: "body"' for CSP-restricted environments.` | ||
| ); | ||
| } | ||
| let cssLoaderPreamble = "function $loadcss(u,m,l){(l=document.createElement('link')).rel='stylesheet';l.href=u;document.head.appendChild(l)}"; | ||
@@ -630,0 +656,0 @@ const lazy = preloadMode === "js-lazy"; |
+29
-3
@@ -1,2 +0,2 @@ | ||
| import { readFile } from 'fs'; | ||
| import { readFile, existsSync, realpathSync } from 'fs'; | ||
| import { selectAll, selectOne } from 'css-select'; | ||
@@ -12,3 +12,11 @@ import { parseDocument, DomUtils } from 'htmlparser2'; | ||
| // src/index.js | ||
| /** | ||
| * @opensourceframework/critters | ||
| * Critical CSS inliner | ||
| * | ||
| * @original-author The Chromium Authors | ||
| * @original-repo https://github.com/GoogleChromeLabs/critters | ||
| * @license Apache-2.0 | ||
| */ | ||
| var classCache = null; | ||
@@ -412,3 +420,16 @@ var idCache = null; | ||
| function isSubpath(basePath, currentPath) { | ||
| return !path.relative(basePath, currentPath).startsWith(".."); | ||
| try { | ||
| const resolvedBase = path.resolve(basePath); | ||
| const resolvedCurrent = path.resolve(currentPath); | ||
| if (existsSync(resolvedBase) && existsSync(resolvedCurrent)) { | ||
| const realBase = realpathSync(resolvedBase); | ||
| const realCurrent = realpathSync(resolvedCurrent); | ||
| const relative2 = path.relative(realBase, realCurrent); | ||
| return !relative2.startsWith("..") && !path.isAbsolute(relative2); | ||
| } | ||
| const relative = path.relative(resolvedBase, resolvedCurrent); | ||
| return !relative.startsWith("..") && !path.isAbsolute(relative); | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
@@ -619,2 +640,7 @@ | ||
| setupLinkPreload(link, href, media, style, document, preloadMode) { | ||
| if (preloadMode === "media" || preloadMode === "swap" || preloadMode === "swap-high") { | ||
| this.logger.warn( | ||
| `CSP Warning: The '${preloadMode}' preload strategy injects inline onload event handlers which may be blocked by Content Security Policy (CSP) directives. Consider using 'preload: "js"' or 'preload: "body"' for CSP-restricted environments.` | ||
| ); | ||
| } | ||
| let cssLoaderPreamble = "function $loadcss(u,m,l){(l=document.createElement('link')).rel='stylesheet';l.href=u;document.head.appendChild(l)}"; | ||
@@ -621,0 +647,0 @@ const lazy = preloadMode === "js-lazy"; |
+3
-5
| { | ||
| "name": "@opensourceframework/critters", | ||
| "version": "2.0.0", | ||
| "version": "2.0.1", | ||
| "description": "Inline critical CSS and lazy-load the rest. Forked from GoogleChromeLabs/critters.", | ||
@@ -73,5 +73,3 @@ "keywords": [ | ||
| "typescript": "^5.3.0", | ||
| "vitest": "^1.0.0", | ||
| "@opensourceframework/eslint-config": "0.0.0", | ||
| "@opensourceframework/tsconfig": "0.0.0" | ||
| "vitest": "^1.0.0" | ||
| }, | ||
@@ -93,3 +91,3 @@ "engines": { | ||
| "clean": "rm -rf dist", | ||
| "test": "vitest run", | ||
| "test": "vitest run --passWithNoTests", | ||
| "test:watch": "vitest", | ||
@@ -96,0 +94,0 @@ "test:coverage": "vitest run --coverage", |
| /** | ||
| * Copyright 2018 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| * use this file except in compliance with the License. You may obtain a copy of | ||
| * the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| */ | ||
| declare class Critters { | ||
| /** | ||
| * Create an instance of Critters with custom options. | ||
| * The `.process()` method can be called repeatedly to re-use this instance and its cache. | ||
| */ | ||
| constructor(options?: Options); | ||
| /** | ||
| * Process an HTML document to inline critical CSS from its stylesheets. | ||
| * @param html String containing a full HTML document to be parsed. | ||
| * @returns A modified copy of the provided HTML with critical CSS inlined. | ||
| */ | ||
| process(html: string): Promise<string>; | ||
| /** | ||
| * Read the contents of a file from the specified filesystem or disk. | ||
| * Override this method to customize how stylesheets are loaded. | ||
| */ | ||
| readFile(filename: string): Promise<string> | string; | ||
| /** | ||
| * Given a stylesheet URL, returns the corresponding CSS asset. | ||
| * Overriding this method requires doing your own URL normalization, so it's generally better to override `readFile()`. | ||
| */ | ||
| getCssAsset(href: string): Promise<string | undefined> | string | undefined; | ||
| } | ||
| interface Options { | ||
| path?: string; | ||
| publicPath?: string; | ||
| external?: boolean; | ||
| inlineThreshold?: number; | ||
| minimumExternalSize?: number; | ||
| pruneSource?: boolean; | ||
| mergeStylesheets?: boolean; | ||
| additionalStylesheets?: string[]; | ||
| preload?: 'body' | 'media' | 'swap' | 'swap-high' | 'js' | 'js-lazy' | false; | ||
| noscriptFallback?: boolean; | ||
| inlineFonts?: boolean; | ||
| preloadFonts?: boolean; | ||
| fonts?: boolean; | ||
| keyframes?: 'critical' | 'all' | 'none' | boolean; | ||
| compress?: boolean; | ||
| logLevel?: 'info' | 'warn' | 'error' | 'trace' | 'debug' | 'silent'; | ||
| reduceInlineStyles?: boolean; | ||
| logger?: Logger; | ||
| allowRules?: (RegExp | string)[]; | ||
| } | ||
| interface Logger { | ||
| trace?: (message: string) => void; | ||
| debug?: (message: string) => void; | ||
| info?: (message: string) => void; | ||
| warn?: (message: string) => void; | ||
| error?: (message: string) => void; | ||
| } | ||
| export { type Logger, type Options, Critters as default }; |
| /** | ||
| * Copyright 2018 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| * use this file except in compliance with the License. You may obtain a copy of | ||
| * the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| */ | ||
| declare class Critters { | ||
| /** | ||
| * Create an instance of Critters with custom options. | ||
| * The `.process()` method can be called repeatedly to re-use this instance and its cache. | ||
| */ | ||
| constructor(options?: Options); | ||
| /** | ||
| * Process an HTML document to inline critical CSS from its stylesheets. | ||
| * @param html String containing a full HTML document to be parsed. | ||
| * @returns A modified copy of the provided HTML with critical CSS inlined. | ||
| */ | ||
| process(html: string): Promise<string>; | ||
| /** | ||
| * Read the contents of a file from the specified filesystem or disk. | ||
| * Override this method to customize how stylesheets are loaded. | ||
| */ | ||
| readFile(filename: string): Promise<string> | string; | ||
| /** | ||
| * Given a stylesheet URL, returns the corresponding CSS asset. | ||
| * Overriding this method requires doing your own URL normalization, so it's generally better to override `readFile()`. | ||
| */ | ||
| getCssAsset(href: string): Promise<string | undefined> | string | undefined; | ||
| } | ||
| interface Options { | ||
| path?: string; | ||
| publicPath?: string; | ||
| external?: boolean; | ||
| inlineThreshold?: number; | ||
| minimumExternalSize?: number; | ||
| pruneSource?: boolean; | ||
| mergeStylesheets?: boolean; | ||
| additionalStylesheets?: string[]; | ||
| preload?: 'body' | 'media' | 'swap' | 'swap-high' | 'js' | 'js-lazy' | false; | ||
| noscriptFallback?: boolean; | ||
| inlineFonts?: boolean; | ||
| preloadFonts?: boolean; | ||
| fonts?: boolean; | ||
| keyframes?: 'critical' | 'all' | 'none' | boolean; | ||
| compress?: boolean; | ||
| logLevel?: 'info' | 'warn' | 'error' | 'trace' | 'debug' | 'silent'; | ||
| reduceInlineStyles?: boolean; | ||
| logger?: Logger; | ||
| allowRules?: (RegExp | string)[]; | ||
| } | ||
| interface Logger { | ||
| trace?: (message: string) => void; | ||
| debug?: (message: string) => void; | ||
| info?: (message: string) => void; | ||
| warn?: (message: string) => void; | ||
| error?: (message: string) => void; | ||
| } | ||
| export { type Logger, type Options, Critters as default }; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
301117
1.29%3
-40%13
-13.33%3341
-0.51%