| 522 | } |
| 523 | |
| 524 | get cssRules() { |
| 525 | if (this._cssRules) return this._cssRules; |
| 526 | |
| 527 | const { |
| 528 | TT_LEFT_CURLY_BRACKET, |
| 529 | TT_RIGHT_CURLY_BRACKET, |
| 530 | TT_SEMICOLON, |
| 531 | readToken |
| 532 | } = require("../../lib/css/syntax"); |
| 533 | |
| 534 | /** @type {CssRule[]} */ |
| 535 | const rules = []; |
| 536 | /** @type {StyleDeclaration} */ |
| 537 | let currentRule = { getPropertyValue }; |
| 538 | /** @type {string | undefined} */ |
| 539 | let selector; |
| 540 | let last = 0; |
| 541 | let ruleStart = 0; // Track the start of the current rule |
| 542 | const processDeclaration = (/** @type {string} */ str) => { |
| 543 | const colon = str.indexOf(":"); |
| 544 | if (colon > 0) { |
| 545 | const property = str.slice(0, colon).trim(); |
| 546 | const value = str.slice(colon + 1); |
| 547 | currentRule[property] = value; |
| 548 | } |
| 549 | }; |
| 550 | const href = /** @type {string} */ (this._element.href).split("?")[0]; // Remove query parameters (e.g., ?hmr=timestamp) |
| 551 | const filepath = /file:\/\//.test(href) |
| 552 | ? new URL(href) |
| 553 | : path.resolve( |
| 554 | this._basePath, |
| 555 | href |
| 556 | .replace(/^https:\/\/test\.cases\/path\//, "") |
| 557 | .replace(/^https:\/\/example\.com\/public\/path\//, "") |
| 558 | .replace(/^https:\/\/example\.com\//, "") |
| 559 | ); |
| 560 | let css = fs.readFileSync(filepath, "utf8"); |
| 561 | css = css |
| 562 | // Remove comments |
| 563 | // @ts-expect-error we use es2018 for such tests |
| 564 | .replace(/\/\*.*?\*\//gs, "") |
| 565 | .replace(/@import url\("([^"]+)"\);/g, (match, url) => { |
| 566 | if (!/^https:\/\/test\.cases\/path\//.test(url)) { |
| 567 | return url; |
| 568 | } |
| 569 | |
| 570 | if (url.startsWith("#")) { |
| 571 | return url; |
| 572 | } |
| 573 | |
| 574 | return fs.readFileSync( |
| 575 | path.resolve( |
| 576 | this._basePath, |
| 577 | url.replace(/^https:\/\/test\.cases\/path\//, "") |
| 578 | ), |
| 579 | "utf8" |
| 580 | ); |
| 581 | }); |