@automattic/jetpack-critical-css-gen 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +16 -4
  2. package/build/browser-interface-iframe.d.ts +31 -0
  3. package/build/browser-interface-iframe.js +130 -0
  4. package/build/browser-interface-iframe.js.map +1 -0
  5. package/build/browser-interface-playwright.d.ts +53 -0
  6. package/build/browser-interface-playwright.js +94 -0
  7. package/build/browser-interface-playwright.js.map +1 -0
  8. package/build/browser-interface.d.ts +77 -0
  9. package/build/browser-interface.js +124 -0
  10. package/build/browser-interface.js.map +1 -0
  11. package/build/browser.d.ts +5 -0
  12. package/build/browser.js +6 -0
  13. package/build/browser.js.map +1 -0
  14. package/build/css-file-set.d.ts +100 -0
  15. package/build/css-file-set.js +210 -0
  16. package/build/css-file-set.js.map +1 -0
  17. package/build/errors.d.ts +101 -0
  18. package/build/errors.js +103 -0
  19. package/build/errors.js.map +1 -0
  20. package/build/generate-critical-css.d.ts +24 -0
  21. package/build/generate-critical-css.js +162 -0
  22. package/build/generate-critical-css.js.map +1 -0
  23. package/build/ignored-pseudo-elements.d.ts +8 -0
  24. package/build/ignored-pseudo-elements.js +35 -0
  25. package/build/ignored-pseudo-elements.js.map +1 -0
  26. package/build/minify-css.d.ts +11 -0
  27. package/build/minify-css.js +19 -0
  28. package/build/minify-css.js.map +1 -0
  29. package/build/object-promise-all.d.ts +12 -0
  30. package/build/object-promise-all.js +16 -0
  31. package/build/object-promise-all.js.map +1 -0
  32. package/build/playwright.d.ts +5 -0
  33. package/build/playwright.js +6 -0
  34. package/build/playwright.js.map +1 -0
  35. package/build/style-ast.d.ts +164 -0
  36. package/build/style-ast.js +540 -0
  37. package/build/style-ast.js.map +1 -0
  38. package/build/types.d.ts +14 -0
  39. package/build/types.js +2 -0
  40. package/build/types.js.map +1 -0
  41. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -5,22 +5,34 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.0.0] - 2024-10-07
8
+ ## [1.0.2] - 2024-11-04
9
+ ### Added
10
+ - Enable test coverage. [#39961]
9
11
 
10
- ### Security
12
+ ### Changed
13
+ - Updated package dependencies. [#39733]
14
+
15
+ ## [1.0.1] - 2024-10-10
16
+ ### Changed
17
+ - Updated package dependencies. [#39670]
11
18
 
19
+ ### Fixed
20
+ - Add missing build folder to package. [#39723]
21
+
22
+ ## [1.0.0] - 2024-10-07
23
+ ### Security
12
24
  - Security: Fix XSS vulnerability. [#39507]
13
25
 
14
26
  ### Added
15
-
16
27
  - Add /playwright entry point for BrowserInterfacePlaywright. [#39509]
17
28
 
18
29
  ### Changed
19
-
20
30
  - Change default entry point of package to include BrowserInterfaceIframe instead of BrowserInterfacePlaywright. [#39509]
21
31
 
22
32
  ## 0.1.0 - 2024-09-24
23
33
  ### Added
24
34
  - Initial version. [#38429]
25
35
 
36
+ [1.0.2]: https://github.com/Automattic/jetpack-critical-css-gen/compare/v1.0.1...v1.0.2
37
+ [1.0.1]: https://github.com/Automattic/jetpack-critical-css-gen/compare/v1.0.0...v1.0.1
26
38
  [1.0.0]: https://github.com/Automattic/jetpack-critical-css-gen/compare/v0.1.0...v1.0.0
@@ -0,0 +1,31 @@
1
+ import { BrowserInterface, BrowserRunnable } from './browser-interface.js';
2
+ import { UrlError } from './errors.js';
3
+ import { Viewport } from './types.js';
4
+ type VerifyMethod = (rawUrl: string, contentWindow: Window, contentDocument: Document) => boolean;
5
+ type BrowserInterfaceIframeOptions = {
6
+ requestGetParameters?: {
7
+ [key: string]: string;
8
+ };
9
+ loadTimeout?: number;
10
+ verifyPage: VerifyMethod;
11
+ allowScripts?: boolean;
12
+ };
13
+ export declare class BrowserInterfaceIframe extends BrowserInterface {
14
+ private requestGetParameters;
15
+ private loadTimeout;
16
+ private verifyPage;
17
+ private currentUrl;
18
+ private currentSize;
19
+ private wrapperDiv;
20
+ private iframe;
21
+ constructor({ requestGetParameters, loadTimeout, verifyPage, allowScripts, }: BrowserInterfaceIframeOptions);
22
+ cleanup(): Promise<void>;
23
+ fetch(url: string, options: RequestInit, _role: 'css' | 'html'): Promise<Response>;
24
+ runInPage<ReturnType>(pageUrl: string, viewport: Viewport | null, method: BrowserRunnable<ReturnType>, ...args: unknown[]): Promise<ReturnType>;
25
+ addGetParameters(rawUrl: string): string;
26
+ diagnoseUrlError(url: string): Promise<UrlError | null>;
27
+ sameOrigin(url: string): boolean;
28
+ loadPage(rawUrl: string): Promise<void>;
29
+ resize({ width, height }: Viewport): Promise<unknown>;
30
+ }
31
+ export {};
@@ -0,0 +1,130 @@
1
+ import { BrowserInterface } from './browser-interface.js';
2
+ import { CrossDomainError, HttpError, LoadTimeoutError, RedirectError, UrlVerifyError, UnknownError, XFrameDenyError, } from './errors.js';
3
+ const defaultLoadTimeout = 60 * 1000;
4
+ export class BrowserInterfaceIframe extends BrowserInterface {
5
+ constructor({ requestGetParameters, loadTimeout, verifyPage, allowScripts, }) {
6
+ super();
7
+ this.requestGetParameters = requestGetParameters || {};
8
+ this.loadTimeout = loadTimeout || defaultLoadTimeout;
9
+ this.verifyPage = verifyPage;
10
+ // Default 'allowScripts' to true if not specified.
11
+ allowScripts = allowScripts !== false;
12
+ this.currentUrl = null;
13
+ this.currentSize = { width: null, height: null };
14
+ // Create a wrapper div to keep the iframe invisible.
15
+ this.wrapperDiv = document.createElement('div');
16
+ this.wrapperDiv.setAttribute('style', 'position:fixed; z-index: -1000; opacity: 0; top: 50px;');
17
+ document.body.append(this.wrapperDiv);
18
+ // Create iframe itself.
19
+ this.iframe = document.createElement('iframe');
20
+ this.iframe.setAttribute('style', 'max-width: none; max-height: none; border: 0px;');
21
+ this.iframe.setAttribute('aria-hidden', 'true');
22
+ this.iframe.setAttribute('sandbox', 'allow-same-origin ' + (allowScripts ? 'allow-scripts' : ''));
23
+ this.wrapperDiv.append(this.iframe);
24
+ }
25
+ async cleanup() {
26
+ this.iframe.remove();
27
+ this.wrapperDiv.remove();
28
+ }
29
+ async fetch(url, options, _role) {
30
+ return window.fetch(url, options);
31
+ }
32
+ async runInPage(pageUrl, viewport, method, ...args) {
33
+ await this.loadPage(pageUrl);
34
+ if (viewport) {
35
+ await this.resize(viewport);
36
+ }
37
+ // The inner window in the iframe is separate from the main window object.
38
+ // Pass the iframe window object to the evaluating method.
39
+ return method({ innerWindow: this.iframe.contentWindow, args });
40
+ }
41
+ addGetParameters(rawUrl) {
42
+ const urlObject = new URL(rawUrl);
43
+ for (const key of Object.keys(this.requestGetParameters)) {
44
+ urlObject.searchParams.append(key, this.requestGetParameters[key]);
45
+ }
46
+ return urlObject.toString();
47
+ }
48
+ async diagnoseUrlError(url) {
49
+ try {
50
+ const response = await this.fetch(url, { redirect: 'manual' }, 'html');
51
+ const headers = response.headers;
52
+ if (headers.get('x-frame-options') === 'DENY') {
53
+ return new XFrameDenyError({ url });
54
+ }
55
+ if (response.type === 'opaqueredirect') {
56
+ return new RedirectError({
57
+ url,
58
+ redirectUrl: response.url,
59
+ });
60
+ }
61
+ if (response.status === 200) {
62
+ return null;
63
+ }
64
+ return new HttpError({ url, code: response.status });
65
+ }
66
+ catch (err) {
67
+ return new UnknownError({ url, message: err.message });
68
+ }
69
+ }
70
+ sameOrigin(url) {
71
+ return new URL(url).origin === window.location.origin;
72
+ }
73
+ async loadPage(rawUrl) {
74
+ if (rawUrl === this.currentUrl) {
75
+ return;
76
+ }
77
+ const fullUrl = this.addGetParameters(rawUrl);
78
+ return new Promise((resolve, rawReject) => {
79
+ // Track all URL errors.
80
+ const reject = err => {
81
+ this.trackUrlError(rawUrl, err);
82
+ rawReject(err);
83
+ };
84
+ // Catch cross-domain errors before they occur.
85
+ if (!this.sameOrigin(fullUrl)) {
86
+ reject(new CrossDomainError({ url: fullUrl }));
87
+ return;
88
+ }
89
+ // Set a timeout.
90
+ const timeoutId = setTimeout(() => {
91
+ this.iframe.onload = null;
92
+ reject(new LoadTimeoutError({ url: fullUrl }));
93
+ }, this.loadTimeout);
94
+ // Catch load event.
95
+ this.iframe.onload = async () => {
96
+ try {
97
+ this.iframe.onload = null;
98
+ clearTimeout(timeoutId);
99
+ // Verify the inner document is readable.
100
+ if (!this.iframe.contentDocument || !this.iframe.contentWindow) {
101
+ throw ((await this.diagnoseUrlError(fullUrl)) || new CrossDomainError({ url: fullUrl }));
102
+ }
103
+ if (!this.verifyPage(rawUrl, this.iframe.contentWindow, this.iframe.contentDocument)) {
104
+ // Diagnose and throw an appropriate error.
105
+ throw ((await this.diagnoseUrlError(fullUrl)) || new UrlVerifyError({ url: fullUrl }));
106
+ }
107
+ this.currentUrl = rawUrl;
108
+ resolve();
109
+ }
110
+ catch (err) {
111
+ reject(err);
112
+ }
113
+ };
114
+ this.iframe.src = fullUrl;
115
+ });
116
+ }
117
+ async resize({ width, height }) {
118
+ if (this.currentSize.width === width && this.currentSize.height === height) {
119
+ return;
120
+ }
121
+ return new Promise(resolve => {
122
+ // Set iframe size.
123
+ this.iframe.width = width.toString();
124
+ this.iframe.height = height.toString();
125
+ // Bounce to browser main loop to allow resize to complete.
126
+ setTimeout(resolve, 1);
127
+ });
128
+ }
129
+ }
130
+ //# sourceMappingURL=browser-interface-iframe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-interface-iframe.js","sourceRoot":"","sources":["../src/browser-interface-iframe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { BrowserContext, Page } from 'playwright-core';
2
+ import { BrowserInterface, BrowserRunnable, FetchOptions } from './browser-interface.js';
3
+ import { Viewport } from './types.js';
4
+ export type Tab = {
5
+ page: Page;
6
+ statusCode: number | null;
7
+ };
8
+ export type TabsByUrl = {
9
+ [url: string]: Tab;
10
+ };
11
+ export declare class BrowserInterfacePlaywright extends BrowserInterface {
12
+ private context;
13
+ private urls;
14
+ private tabs;
15
+ /**
16
+ * Creates a new BrowserInterfacePlaywright instance.
17
+ *
18
+ * @param {BrowserContext} context - The playwright browser context to work with.
19
+ * @param {string[]} urls - Array of urls to evaluate. The reason we are taking this as an argument is because we want to load all of them in parallel.
20
+ */
21
+ constructor(context: BrowserContext, urls: string[]);
22
+ private getTabs;
23
+ /**
24
+ * Open an array of urls in a new browser context.
25
+ *
26
+ * Take a browser instance and an array of urls to open in new tabs.
27
+ *
28
+ * @param {BrowserContext} context - Browser context to use.
29
+ * @param {string[]} urls - Array of urls to open.
30
+ * @return {Promise< TabsByUrl >} Promise resolving to the browser context.
31
+ */
32
+ private openUrls;
33
+ /**
34
+ * Open url in a new tab in a given browserContext.
35
+ *
36
+ * @param {BrowserContext} browserContext - Browser context to use.
37
+ * @param {string} url - Url to open.
38
+ * @return {Promise<Page>} Promise resolving to the page instance.
39
+ */
40
+ private newTab;
41
+ runInPage<ReturnType>(pageUrl: string, viewport: Viewport | null, method: BrowserRunnable<ReturnType>, ...args: unknown[]): Promise<ReturnType>;
42
+ /**
43
+ * Replacement for browser.fetch, uses node's fetch to simulate the same
44
+ * interface.
45
+ *
46
+ * @param {string} url - URL to fetch.
47
+ * @param {object} options - Fetch options.
48
+ * @param {string} _role - 'css' or 'html' indicating what kind of thing is being fetched.
49
+ * @return {Promise<Response>} A promise that resolves to the fetch response.
50
+ */
51
+ fetch(url: string, options: FetchOptions, _role: 'css' | 'html'): Promise<Response>;
52
+ private isOkStatus;
53
+ }
@@ -0,0 +1,94 @@
1
+ import { BrowserInterface } from './browser-interface.js';
2
+ import { HttpError } from './errors.js';
3
+ import { objectPromiseAll } from './object-promise-all.js';
4
+ const PAGE_GOTO_TIMEOUT_MS = 5 * 60 * 1000;
5
+ export class BrowserInterfacePlaywright extends BrowserInterface {
6
+ /**
7
+ * Creates a new BrowserInterfacePlaywright instance.
8
+ *
9
+ * @param {BrowserContext} context - The playwright browser context to work with.
10
+ * @param {string[]} urls - Array of urls to evaluate. The reason we are taking this as an argument is because we want to load all of them in parallel.
11
+ */
12
+ constructor(context, urls) {
13
+ super();
14
+ this.context = context;
15
+ this.urls = urls;
16
+ }
17
+ async getTabs() {
18
+ if (typeof this.tabs === 'undefined') {
19
+ await this.openUrls(this.context, this.urls);
20
+ }
21
+ return this.tabs;
22
+ }
23
+ /**
24
+ * Open an array of urls in a new browser context.
25
+ *
26
+ * Take a browser instance and an array of urls to open in new tabs.
27
+ *
28
+ * @param {BrowserContext} context - Browser context to use.
29
+ * @param {string[]} urls - Array of urls to open.
30
+ * @return {Promise< TabsByUrl >} Promise resolving to the browser context.
31
+ */
32
+ async openUrls(context, urls) {
33
+ this.tabs = await objectPromiseAll(urls.reduce((set, url) => {
34
+ set[url] = this.newTab(context, url);
35
+ return set;
36
+ }, {}));
37
+ }
38
+ /**
39
+ * Open url in a new tab in a given browserContext.
40
+ *
41
+ * @param {BrowserContext} browserContext - Browser context to use.
42
+ * @param {string} url - Url to open.
43
+ * @return {Promise<Page>} Promise resolving to the page instance.
44
+ */
45
+ async newTab(browserContext, url) {
46
+ const tab = {
47
+ page: await browserContext.newPage(),
48
+ statusCode: null,
49
+ };
50
+ tab.page.on('response', async (response) => {
51
+ if (response.url() === url) {
52
+ tab.statusCode = response.status();
53
+ }
54
+ });
55
+ await tab.page.goto(url, { timeout: PAGE_GOTO_TIMEOUT_MS });
56
+ return tab;
57
+ }
58
+ async runInPage(pageUrl, viewport, method, ...args) {
59
+ const tabs = await this.getTabs();
60
+ const tab = tabs[pageUrl];
61
+ if (!tab || !tab.page) {
62
+ throw new Error(`Playwright interface does not include URL ${pageUrl}`);
63
+ }
64
+ // Bail early if the page returned a non-200 status code.
65
+ if (!tab.statusCode || !this.isOkStatus(tab.statusCode)) {
66
+ const error = new HttpError({ url: pageUrl, code: tab.statusCode });
67
+ this.trackUrlError(pageUrl, error);
68
+ throw error;
69
+ }
70
+ if (viewport) {
71
+ await tab.page.setViewportSize(viewport);
72
+ }
73
+ // The inner window in Playwright is the directly accessible main window object.
74
+ // The evaluating method does not need a separate window object.
75
+ // Call inner method within the Playwright context.
76
+ return tab.page.evaluate(method, { innerWindow: null, args });
77
+ }
78
+ /**
79
+ * Replacement for browser.fetch, uses node's fetch to simulate the same
80
+ * interface.
81
+ *
82
+ * @param {string} url - URL to fetch.
83
+ * @param {object} options - Fetch options.
84
+ * @param {string} _role - 'css' or 'html' indicating what kind of thing is being fetched.
85
+ * @return {Promise<Response>} A promise that resolves to the fetch response.
86
+ */
87
+ async fetch(url, options, _role) {
88
+ return fetch(url, options);
89
+ }
90
+ isOkStatus(statusCode) {
91
+ return statusCode >= 200 && statusCode < 300;
92
+ }
93
+ }
94
+ //# sourceMappingURL=browser-interface-playwright.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-interface-playwright.js","sourceRoot":"","sources":["../src/browser-interface-playwright.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import type { Viewport } from './types.js';
2
+ export type BrowserRunnable<ReturnType> = (arg: unknown) => ReturnType;
3
+ export interface FetchOptions {
4
+ method?: 'POST' | 'GET';
5
+ }
6
+ export interface FetchResponse {
7
+ ok: boolean;
8
+ status: number;
9
+ text: () => Promise<string>;
10
+ }
11
+ export declare class BrowserInterface {
12
+ private urlErrors;
13
+ constructor();
14
+ trackUrlError(url: string, error: Error): void;
15
+ filterValidUrls(urls: string[]): string[];
16
+ runInPage<ReturnType>(_pageUrl: string, _viewport: Viewport | null, _method: BrowserRunnable<ReturnType>, ..._args: unknown[]): Promise<ReturnType>;
17
+ /**
18
+ * Context-specific wrapper for fetch; uses window.fetch in browsers, or a
19
+ * node library when using Puppeteer.
20
+ *
21
+ * @param {string} _url - The URL to fetch
22
+ * @param {FetchOptions} _options - Fetch options
23
+ * @param {'css' | 'html'} _role - Role of the fetch operation
24
+ */
25
+ fetch(_url: string, _options: FetchOptions, _role: 'css' | 'html'): Promise<FetchResponse>;
26
+ cleanup(): Promise<void>;
27
+ getCssIncludes(pageUrl: string): Promise<{
28
+ [url: string]: {
29
+ media: string;
30
+ };
31
+ }>;
32
+ static innerGetCssIncludes({ innerWindow }: {
33
+ innerWindow: any;
34
+ }): any;
35
+ getInternalStyles(pageUrl: string): Promise<string>;
36
+ /**
37
+ * Get all internal styles as a combined string from the window.
38
+ *
39
+ * @param {object} wrappedArgs - Object containing the inner window.
40
+ * @param {Window} wrappedArgs.innerWindow - Window inside the browser interface.
41
+ * @return {string} Combined internal styles as a string.
42
+ */
43
+ static innerGetInternalStyles({ innerWindow }: {
44
+ innerWindow: any;
45
+ }): string;
46
+ /**
47
+ * Given a set of CSS selectors (as object keys), along with "simplified" versions
48
+ * for easy querySelector calling (values), return an array of selectors which match
49
+ * _any_ element on the page.
50
+ *
51
+ * @param {object} wrappedArgs - Object containing the inner window and arguments.
52
+ * @param {Window} wrappedArgs.innerWindow - Window inside the browser interface.
53
+ * @param {Object[]} wrappedArgs.args - Array of arguments.
54
+ * {Object} wrappedArgs.args[selectors] - Map containing selectors (object keys), and simplified versions for easy matching (values).
55
+ * @return {string[]} Array of selectors matching above-the-fold elements.
56
+ */
57
+ static innerFindMatchingSelectors({ innerWindow, args: [selectors] }: {
58
+ innerWindow: any;
59
+ args: [any];
60
+ }): string[];
61
+ /**
62
+ * Given a set of CSS selectors (as object keys), along with "simplified" versions
63
+ * for easy querySelector calling (values), return an array of selectors which match
64
+ * any above-the-fold element on the page.
65
+ *
66
+ * @param {object} wrappedArgs - Object containing the inner window and arguments.
67
+ * @param {Window} wrappedArgs.innerWindow - Window inside the browser interface.
68
+ * @param {Object[]} wrappedArgs.args - Array of arguments.
69
+ * {Object} wrappedArgs.args[selectors] - Map containing selectors (object keys), and simplified versions for easy matching (values).
70
+ * {string[]} wrappedArgs.args[pageSelectors] - String array containing selectors that appear anywhere on this page (as returned by innerFindMatchingSelectors) - should be a subset of keys in selectors.
71
+ * @return {string[]} Array of selectors matching above-the-fold elements.
72
+ */
73
+ static innerFindAboveFoldSelectors({ innerWindow, args: [selectors, pageSelectors], }: {
74
+ innerWindow: any;
75
+ args: [any, any];
76
+ }): string[];
77
+ }
@@ -0,0 +1,124 @@
1
+ export class BrowserInterface {
2
+ constructor() {
3
+ this.urlErrors = {};
4
+ }
5
+ trackUrlError(url, error) {
6
+ this.urlErrors[url] = error;
7
+ }
8
+ filterValidUrls(urls) {
9
+ return urls.filter(url => !this.urlErrors[url]);
10
+ }
11
+ async runInPage(_pageUrl, _viewport, _method, ..._args) {
12
+ throw new Error('Undefined interface method: BrowserInterface.runInPage()');
13
+ }
14
+ /**
15
+ * Context-specific wrapper for fetch; uses window.fetch in browsers, or a
16
+ * node library when using Puppeteer.
17
+ *
18
+ * @param {string} _url - The URL to fetch
19
+ * @param {FetchOptions} _options - Fetch options
20
+ * @param {'css' | 'html'} _role - Role of the fetch operation
21
+ */
22
+ async fetch(_url, _options, _role) {
23
+ throw new Error('Undefined interface method: BrowserInterface.fetch()');
24
+ }
25
+ async cleanup() {
26
+ // No-op.
27
+ }
28
+ async getCssIncludes(pageUrl) {
29
+ return await this.runInPage(pageUrl, null, BrowserInterface.innerGetCssIncludes);
30
+ }
31
+ static innerGetCssIncludes({ innerWindow }) {
32
+ innerWindow = null === innerWindow ? window : innerWindow;
33
+ return [...innerWindow.document.getElementsByTagName('link')]
34
+ .filter(link => link.rel === 'stylesheet')
35
+ .reduce((set, link) => {
36
+ set[link.href] = {
37
+ media: link.media || null,
38
+ };
39
+ return set;
40
+ }, {});
41
+ }
42
+ async getInternalStyles(pageUrl) {
43
+ return await this.runInPage(pageUrl, null, BrowserInterface.innerGetInternalStyles);
44
+ }
45
+ /**
46
+ * Get all internal styles as a combined string from the window.
47
+ *
48
+ * @param {object} wrappedArgs - Object containing the inner window.
49
+ * @param {Window} wrappedArgs.innerWindow - Window inside the browser interface.
50
+ * @return {string} Combined internal styles as a string.
51
+ */
52
+ static innerGetInternalStyles({ innerWindow }) {
53
+ innerWindow = null === innerWindow ? window : innerWindow;
54
+ const styleElements = Array.from(innerWindow.document.getElementsByTagName('style'));
55
+ return styleElements.reduce((styles, style) => {
56
+ styles += style.innerText;
57
+ return styles;
58
+ }, '');
59
+ }
60
+ /**
61
+ * Given a set of CSS selectors (as object keys), along with "simplified" versions
62
+ * for easy querySelector calling (values), return an array of selectors which match
63
+ * _any_ element on the page.
64
+ *
65
+ * @param {object} wrappedArgs - Object containing the inner window and arguments.
66
+ * @param {Window} wrappedArgs.innerWindow - Window inside the browser interface.
67
+ * @param {Object[]} wrappedArgs.args - Array of arguments.
68
+ * {Object} wrappedArgs.args[selectors] - Map containing selectors (object keys), and simplified versions for easy matching (values).
69
+ * @return {string[]} Array of selectors matching above-the-fold elements.
70
+ */
71
+ static innerFindMatchingSelectors({ innerWindow, args: [selectors] }) {
72
+ innerWindow = null === innerWindow ? window : innerWindow;
73
+ return Object.keys(selectors).filter(selector => {
74
+ try {
75
+ return !!innerWindow.document.querySelector(selectors[selector]);
76
+ }
77
+ catch (err) {
78
+ // Ignore invalid selectors.
79
+ return false;
80
+ }
81
+ });
82
+ }
83
+ /**
84
+ * Given a set of CSS selectors (as object keys), along with "simplified" versions
85
+ * for easy querySelector calling (values), return an array of selectors which match
86
+ * any above-the-fold element on the page.
87
+ *
88
+ * @param {object} wrappedArgs - Object containing the inner window and arguments.
89
+ * @param {Window} wrappedArgs.innerWindow - Window inside the browser interface.
90
+ * @param {Object[]} wrappedArgs.args - Array of arguments.
91
+ * {Object} wrappedArgs.args[selectors] - Map containing selectors (object keys), and simplified versions for easy matching (values).
92
+ * {string[]} wrappedArgs.args[pageSelectors] - String array containing selectors that appear anywhere on this page (as returned by innerFindMatchingSelectors) - should be a subset of keys in selectors.
93
+ * @return {string[]} Array of selectors matching above-the-fold elements.
94
+ */
95
+ static innerFindAboveFoldSelectors({ innerWindow, args: [selectors, pageSelectors], }) {
96
+ /**
97
+ * Inner helper function used inside browser / iframe to check if the given
98
+ * element is "above the fold".
99
+ *
100
+ * @param {HTMLElement} element - Element to check.
101
+ */
102
+ innerWindow = null === innerWindow ? window : innerWindow;
103
+ const isAboveFold = element => {
104
+ const originalClearStyle = element.style.clear || '';
105
+ element.style.clear = 'none';
106
+ const rect = element.getBoundingClientRect();
107
+ element.style.clear = originalClearStyle;
108
+ return rect.top < innerWindow.innerHeight;
109
+ };
110
+ return pageSelectors.filter(s => {
111
+ if ('*' === selectors[s]) {
112
+ return true;
113
+ }
114
+ const matches = innerWindow.document.querySelectorAll(selectors[s]);
115
+ for (const match of matches) {
116
+ if (isAboveFold(match)) {
117
+ return true;
118
+ }
119
+ }
120
+ return false;
121
+ });
122
+ }
123
+ }
124
+ //# sourceMappingURL=browser-interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-interface.js","sourceRoot":"","sources":["../src/browser-interface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { BrowserInterfaceIframe } from './browser-interface-iframe.js';
2
+ export { BrowserInterface } from './browser-interface.js';
3
+ export { generateCriticalCSS } from './generate-critical-css.js';
4
+ export * from './errors.js';
5
+ export declare const version = "0.0.11";
@@ -0,0 +1,6 @@
1
+ export { BrowserInterfaceIframe } from './browser-interface-iframe.js';
2
+ export { BrowserInterface } from './browser-interface.js';
3
+ export { generateCriticalCSS } from './generate-critical-css.js';
4
+ export * from './errors.js';
5
+ export const version = '0.0.11';
6
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,cAAc,aAAa,CAAC;AAE5B,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC"}