Skip to content

Commit 6290bb9

Browse files
authored
fix: [#1727] Fixes issue where it was not possible to nest media, supports and container rules (#1734)
1 parent 2f709e4 commit 6290bb9

20 files changed

+508
-89
lines changed

packages/happy-dom/src/browser/DefaultBrowserSettings.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export default <IBrowserSettings>{
3939
device: {
4040
prefersColorScheme: 'light',
4141
prefersReducedMotion: 'no-preference',
42-
mediaType: 'screen'
42+
mediaType: 'screen',
43+
forcedColors: 'none'
4344
},
4445
debug: {
4546
traceWaitUntilComplete: -1

packages/happy-dom/src/browser/types/IBrowserSettings.ts

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export default interface IBrowserSettings {
111111
prefersColorScheme: string;
112112
prefersReducedMotion: string;
113113
mediaType: string;
114+
forcedColors: string;
114115
};
115116

116117
/**

packages/happy-dom/src/browser/types/IOptionalBrowserSettings.ts

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export default interface IOptionalBrowserSettings {
105105
prefersColorScheme?: string;
106106
prefersReducedMotion?: string;
107107
mediaType?: string;
108+
forcedColors?: string;
108109
};
109110

110111
/**

packages/happy-dom/src/css/CSSRule.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default class CSSRule {
2929
// Public properties
3030
public parentRule: CSSRule = null;
3131
public parentStyleSheet: CSSStyleSheet = null;
32-
public type: number = null;
32+
public type: CSSRuleTypeEnum | null = null;
3333

3434
/**
3535
* Constructor.

packages/happy-dom/src/css/CSSStyleSheet.ts

+26-10
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,27 @@ export default class CSSStyleSheet {
5757
* @returns The newly inserterted rule's index.
5858
*/
5959
public insertRule(rule: string, index?: number): number {
60-
const rules = CSSParser.parseFromString(this, rule);
61-
62-
if (rules.length === 0) {
63-
throw new this[PropertySymbol.window].DOMException(
64-
'Invalid CSS rule.',
65-
DOMExceptionNameEnum.hierarchyRequestError
60+
if (arguments.length === 0) {
61+
throw new this[PropertySymbol.window].TypeError(
62+
`Failed to execute 'insertRule' on 'CSSStyleSheet': 1 argument required, but only 0 present.`
6663
);
6764
}
6865

69-
if (rules.length > 1) {
66+
const rules = CSSParser.parseFromString(this, rule);
67+
68+
if (rules.length === 0 || rules.length > 1) {
7069
throw new this[PropertySymbol.window].DOMException(
71-
'Only one rule is allowed to be added.',
70+
`Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '${rule}'.`,
7271
DOMExceptionNameEnum.syntaxError
7372
);
7473
}
7574

7675
if (index !== undefined) {
7776
if (index > this.cssRules.length) {
7877
throw new this[PropertySymbol.window].DOMException(
79-
'Index is more than the length of CSSRuleList.',
78+
`Failed to execute 'insertRule' on 'CSSStyleSheet': The index provided (${index}) is larger than the maximum index (${
79+
this.cssRules.length - 1
80+
}).`,
8081
DOMExceptionNameEnum.indexSizeError
8182
);
8283
}
@@ -98,7 +99,12 @@ export default class CSSStyleSheet {
9899
* @param index Index.
99100
*/
100101
public deleteRule(index: number): void {
101-
delete this.cssRules[index];
102+
if (arguments.length === 0) {
103+
throw new this[PropertySymbol.window].TypeError(
104+
`Failed to execute 'deleteRule' on 'CSSStyleSheet': 1 argument required, but only 0 present.`
105+
);
106+
}
107+
this.cssRules.splice(index, 1);
102108
}
103109

104110
/**
@@ -109,6 +115,11 @@ export default class CSSStyleSheet {
109115
* @returns Promise.
110116
*/
111117
public async replace(text: string): Promise<void> {
118+
if (arguments.length === 0) {
119+
throw new this[PropertySymbol.window].TypeError(
120+
`Failed to execute 'replace' on 'CSSStyleSheet': 1 argument required, but only 0 present.`
121+
);
122+
}
112123
this.replaceSync(text);
113124
}
114125

@@ -119,6 +130,11 @@ export default class CSSStyleSheet {
119130
* @param text CSS text.
120131
*/
121132
public replaceSync(text: string): void {
133+
if (arguments.length === 0) {
134+
throw new this[PropertySymbol.window].TypeError(
135+
`Failed to execute 'replaceSync' on 'CSSStyleSheet': 1 argument required, but only 0 present.`
136+
);
137+
}
122138
if (this.#currentText !== text) {
123139
this.#currentText = text;
124140
(<CSSRule[]>this.cssRules) = CSSParser.parseFromString(this, text);

packages/happy-dom/src/css/rules/CSSContainerRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import CSSRule from '../CSSRule.js';
2+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
23

34
/**
45
* CSSRule interface.
56
*/
67
export default class CSSContainerRule extends CSSRule {
7-
public readonly type = CSSRule.CONTAINER_RULE;
8+
public readonly type = CSSRuleTypeEnum.containerRule;
89
public readonly cssRules: CSSRule[] = [];
910
public readonly conditionText = '';
1011

packages/happy-dom/src/css/rules/CSSFontFaceRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import CSSRule from '../CSSRule.js';
22
import * as PropertySymbol from '../../PropertySymbol.js';
33
import CSSStyleDeclaration from '../declaration/CSSStyleDeclaration.js';
4+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
45

56
/**
67
* CSSRule interface.
78
*/
89
export default class CSSFontFaceRule extends CSSRule {
9-
public readonly type = CSSRule.FONT_FACE_RULE;
10+
public readonly type = CSSRuleTypeEnum.fontFaceRule;
1011
public [PropertySymbol.cssText] = '';
1112
#style: CSSStyleDeclaration | null = null;
1213

packages/happy-dom/src/css/rules/CSSKeyframeRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import CSSRule from '../CSSRule.js';
22
import * as PropertySymbol from '../../PropertySymbol.js';
33
import CSSStyleDeclaration from '../declaration/CSSStyleDeclaration.js';
4+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
45

56
/**
67
* CSSRule interface.
78
*/
89
export default class CSSKeyframeRule extends CSSRule {
9-
public readonly type = CSSRule.KEYFRAME_RULE;
10+
public readonly type = CSSRuleTypeEnum.keyframeRule;
1011
public readonly keyText: string;
1112
public [PropertySymbol.cssText] = '';
1213
#style: CSSStyleDeclaration | null = null;

packages/happy-dom/src/css/rules/CSSKeyframesRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import CSSRule from '../CSSRule.js';
22
import CSSStyleDeclaration from '../declaration/CSSStyleDeclaration.js';
33
import CSSKeyframeRule from './CSSKeyframeRule.js';
44
import * as PropertySymbol from '../../PropertySymbol.js';
5+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
56

67
const CSS_RULE_REGEXP = /([^{]+){([^}]+)}/;
78

89
/**
910
* CSSRule interface.
1011
*/
1112
export default class CSSKeyframesRule extends CSSRule {
12-
public readonly type = CSSRule.KEYFRAMES_RULE;
13+
public readonly type = CSSRuleTypeEnum.keyframesRule;
1314
public readonly cssRules: CSSKeyframeRule[] = [];
1415
public readonly name: string = null;
1516

packages/happy-dom/src/css/rules/CSSMediaRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import CSSRule from '../CSSRule.js';
2+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
23
import MediaList from '../MediaList.js';
34

45
/**
56
* CSSRule interface.
67
*/
78
export default class CSSMediaRule extends CSSRule {
8-
public readonly type = CSSRule.MEDIA_RULE;
9+
public readonly type = CSSRuleTypeEnum.mediaRule;
910
public readonly cssRules: CSSRule[] = [];
1011
public readonly media = new MediaList();
1112

packages/happy-dom/src/css/rules/CSSStyleRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import CSSRule from '../CSSRule.js';
22
import * as PropertySymbol from '../../PropertySymbol.js';
33
import CSSStyleDeclaration from '../declaration/CSSStyleDeclaration.js';
4+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
45

56
/**
67
* CSSRule interface.
78
*/
89
export default class CSSStyleRule extends CSSRule {
9-
public readonly type = CSSRule.STYLE_RULE;
10+
public readonly type = CSSRuleTypeEnum.styleRule;
1011
public readonly styleMap = new Map();
1112
public selectorText = '';
1213
public [PropertySymbol.cssText] = '';

packages/happy-dom/src/css/rules/CSSSupportsRule.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import CSSRule from '../CSSRule.js';
2+
import CSSRuleTypeEnum from '../CSSRuleTypeEnum.js';
23

34
/**
45
* CSSRule interface.
56
*/
67
export default class CSSSupportsRule extends CSSRule {
7-
public readonly type = CSSRule.SUPPORTS_RULE;
8+
public readonly type = CSSRuleTypeEnum.supportsRule;
89
public readonly cssRules: CSSRule[] = [];
910
public readonly conditionText = '';
1011

0 commit comments

Comments
 (0)