diff --git a/lib/css/CssParser.js b/lib/css/CssParser.js index 33383eaa699..2e6a0878183 100644 --- a/lib/css/CssParser.js +++ b/lib/css/CssParser.js @@ -279,8 +279,8 @@ class CssParser extends Parser { module.addDependency(dep); declaredCssVariables.add(name); } else if ( - propertyName === "animation-name" || - propertyName === "animation" + propertyName.toLowerCase() === "animation-name" || + propertyName.toLowerCase() === "animation" ) { modeData = "animation"; lastIdentifier = undefined; @@ -343,7 +343,7 @@ class CssParser extends Parser { return end; }, atKeyword: (input, start, end) => { - const name = input.slice(start, end); + const name = input.slice(start, end).toLowerCase(); if (name === "@namespace") { throw new Error("@namespace is not supported in bundled CSS"); } @@ -543,7 +543,7 @@ class CssParser extends Parser { singleClassSelector = false; switch (mode) { case CSS_MODE_TOP_LEVEL: { - const name = input.slice(start, end); + const name = input.slice(start, end).toLowerCase(); if (this.allowModeSwitch && name === ":global") { modeData = "global"; const dep = new ConstDependency("", [start, end]); @@ -566,7 +566,7 @@ class CssParser extends Parser { pseudoFunction: (input, start, end) => { switch (mode) { case CSS_MODE_TOP_LEVEL: { - const name = input.slice(start, end - 1); + const name = input.slice(start, end - 1).toLowerCase(); if (this.allowModeSwitch && name === ":global") { modeStack.push(modeData); modeData = "global"; @@ -589,7 +589,7 @@ class CssParser extends Parser { function: (input, start, end) => { switch (mode) { case CSS_MODE_IN_LOCAL_RULE: { - const name = input.slice(start, end - 1); + const name = input.slice(start, end - 1).toLowerCase(); if (name === "var") { let pos = walkCssTokens.eatWhitespaceAndComments(input, end); if (pos === input.length) return pos; diff --git a/lib/css/walkCssTokens.js b/lib/css/walkCssTokens.js index 6ba1dcaabb3..26276b10a43 100644 --- a/lib/css/walkCssTokens.js +++ b/lib/css/walkCssTokens.js @@ -62,6 +62,7 @@ const CC_LOWER_E = "e".charCodeAt(0); const CC_LOWER_Z = "z".charCodeAt(0); const CC_UPPER_A = "A".charCodeAt(0); const CC_UPPER_E = "E".charCodeAt(0); +const CC_UPPER_U = "U".charCodeAt(0); const CC_UPPER_Z = "Z".charCodeAt(0); const CC_0 = "0".charCodeAt(0); const CC_9 = "9".charCodeAt(0); @@ -288,7 +289,10 @@ const consumeOtherIdentifier = (input, pos, callbacks) => { const consumePotentialUrl = (input, pos, callbacks) => { const start = pos; pos = _consumeIdentifier(input, pos); - if (pos === start + 3 && input.slice(start, pos + 1) === "url(") { + if ( + pos === start + 3 && + input.slice(start, pos + 1).toLowerCase() === "url(" + ) { pos++; let cc = input.charCodeAt(pos); while (_isWhiteSpace(cc)) { @@ -569,6 +573,7 @@ const CHAR_MAP = Array.from({ length: 0x80 }, (_, cc) => { case CC_AT_SIGN: return consumeAt; case CC_LOWER_U: + case CC_UPPER_U: return consumePotentialUrl; case CC_LOW_LINE: return consumeOtherIdentifier; diff --git a/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap b/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap index 417c4bbfd68..af7e390a3dc 100644 --- a/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap +++ b/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap @@ -15,6 +15,8 @@ Object { "j": " green url(img\\\\ img.09a1a1112c577c279435.png) xyz", "k": " green url(img\\\\ img.09a1a1112c577c279435.png) xyz", "l": " green url(img.09a1a1112c577c279435.png) xyz", + "m": " green url(img.09a1a1112c577c279435.png) xyz", + "n": " green url(img.09a1a1112c577c279435.png) xyz", } `; diff --git a/test/__snapshots__/ConfigTestCases.basictest.js.snap b/test/__snapshots__/ConfigTestCases.basictest.js.snap index d475303c830..55b67fa8c54 100644 --- a/test/__snapshots__/ConfigTestCases.basictest.js.snap +++ b/test/__snapshots__/ConfigTestCases.basictest.js.snap @@ -15,6 +15,8 @@ Object { "j": " green url(img\\\\ img.09a1a1112c577c279435.png) xyz", "k": " green url(img\\\\ img.09a1a1112c577c279435.png) xyz", "l": " green url(img.09a1a1112c577c279435.png) xyz", + "m": " green url(img.09a1a1112c577c279435.png) xyz", + "n": " green url(img.09a1a1112c577c279435.png) xyz", } `; diff --git a/test/configCases/css/css-modules-in-node/index.js b/test/configCases/css/css-modules-in-node/index.js index e7b6603297b..ffebb43946a 100644 --- a/test/configCases/css/css-modules-in-node/index.js +++ b/test/configCases/css/css-modules-in-node/index.js @@ -53,6 +53,18 @@ it("should allow to create css modules", done => { supportsInMedia: prod ? "my-app-491-SQ" : "./style.module.css-displayFlexInSupportsInMedia", + displayFlexInSupportsInMediaUpperCase: prod + ? "my-app-491-XM" + : "./style.module.css-displayFlexInSupportsInMediaUpperCase", + keyframesUPPERCASE: prod + ? "my-app-491-T4" + : "./style.module.css-localkeyframesUPPERCASE", + localkeyframes2UPPPERCASE: prod + ? "my-app-491-Xi" + : "./style.module.css-localkeyframes2UPPPERCASE", + VARS: prod + ? "--my-app-491-DJ my-app-491-ms undefined my-app-491-cU" + : "--./style.module.css-LOCAL-COLOR ./style.module.css-VARS undefined ./style.module.css-globalVarsUpperCase", }); } catch (e) { return done(e); diff --git a/test/configCases/css/css-modules/index.js b/test/configCases/css/css-modules/index.js index 8fb2375c18e..1f81266de43 100644 --- a/test/configCases/css/css-modules/index.js +++ b/test/configCases/css/css-modules/index.js @@ -56,6 +56,18 @@ it("should allow to create css modules", done => { supportsInMedia: prod ? "my-app-491-SQ" : "./style.module.css-displayFlexInSupportsInMedia", + displayFlexInSupportsInMediaUpperCase: prod + ? "my-app-491-XM" + : "./style.module.css-displayFlexInSupportsInMediaUpperCase", + keyframesUPPERCASE: prod + ? "my-app-491-T4" + : "./style.module.css-localkeyframesUPPERCASE", + localkeyframes2UPPPERCASE: prod + ? "my-app-491-Xi" + : "./style.module.css-localkeyframes2UPPPERCASE", + VARS: prod + ? "--my-app-491-DJ my-app-491-ms undefined my-app-491-cU" + : "--./style.module.css-LOCAL-COLOR ./style.module.css-VARS undefined ./style.module.css-globalVarsUpperCase", }); } catch (e) { return done(e); diff --git a/test/configCases/css/css-modules/style.module.css b/test/configCases/css/css-modules/style.module.css index 8e98a3db9a2..da1dc236bf1 100644 --- a/test/configCases/css/css-modules/style.module.css +++ b/test/configCases/css/css-modules/style.module.css @@ -166,3 +166,56 @@ } } } + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + .displayFlexInSupportsInMediaUpperCase { + display: flex; + } + } +} + +.animationUpperCase { + ANIMATION-NAME: localkeyframesUPPERCASE; + ANIMATION: 3s ease-in 1s 2 reverse both paused localkeyframesUPPERCASE, localkeyframes2UPPPERCASE; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +@KEYFRAMES localkeyframesUPPERCASE { + 0% { + left: VAR(--pos1x); + top: VAR(--pos1y); + color: VAR(--theme-color1); + } + 100% { + left: VAR(--pos2x); + top: VAR(--pos2y); + color: VAR(--theme-color2); + } +} + +@KEYframes localkeyframes2UPPPERCASE { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +:GLOBAL .globalUpperCase :LOCAL .localUpperCase { + color: yellow; +} + +.VARS { + color: VAR(--LOCAL-COLOR); + --LOCAL-COLOR: red; +} + +.globalVarsUpperCase :GLOBAL { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} diff --git a/test/configCases/css/css-modules/use-style.js b/test/configCases/css/css-modules/use-style.js index e3f624a9991..9013436b2cb 100644 --- a/test/configCases/css/css-modules/use-style.js +++ b/test/configCases/css/css-modules/use-style.js @@ -19,6 +19,8 @@ export default { webkitAnyWmultiParams: `${style.local16}`, ident, keyframes: style.localkeyframes, + keyframesUPPERCASE: style.localkeyframesUPPERCASE, + localkeyframes2UPPPERCASE: style.localkeyframes2UPPPERCASE, animation: style.animation, vars: `${style["local-color"]} ${style.vars} ${style["global-color"]} ${style.globalVars}`, media: style.wideScreenClass, @@ -27,4 +29,6 @@ export default { supportsWithOperator: style.floatRightInNegativeSupports, mediaInSupports: style.displayFlexInMediaInSupports, supportsInMedia: style.displayFlexInSupportsInMedia, + displayFlexInSupportsInMediaUpperCase: style.displayFlexInSupportsInMediaUpperCase, + VARS: `${style["LOCAL-COLOR"]} ${style.VARS} ${style["GLOBAL-COLOR"]} ${style.globalVarsUpperCase}`, }; diff --git a/test/configCases/css/css-modules/warnings.js b/test/configCases/css/css-modules/warnings.js index 36ade9aede3..8052a28b9e3 100644 --- a/test/configCases/css/css-modules/warnings.js +++ b/test/configCases/css/css-modules/warnings.js @@ -2,7 +2,9 @@ module.exports = [ [/export 'global' \(imported as 'style'\) was not found/], [/export 'nested2' \(imported as 'style'\) was not found/], [/export 'global-color' \(imported as 'style'\) was not found/], + [/export 'GLOBAL-COLOR' \(imported as 'style'\) was not found/], [/export 'global' \(imported as 'style'\) was not found/], [/export 'nested2' \(imported as 'style'\) was not found/], - [/export 'global-color' \(imported as 'style'\) was not found/] + [/export 'global-color' \(imported as 'style'\) was not found/], + [/export 'GLOBAL-COLOR' \(imported as 'style'\) was not found/] ]; diff --git a/test/configCases/css/import-different-case/index.js b/test/configCases/css/import-different-case/index.js new file mode 100644 index 00000000000..652fef343dd --- /dev/null +++ b/test/configCases/css/import-different-case/index.js @@ -0,0 +1,8 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", () => { + expect(style).toEqual(nsObj({})); + const computedStyle = getComputedStyle(document.body); + expect(computedStyle.getPropertyValue("background")).toBe(" red"); + expect(computedStyle.getPropertyValue("margin")).toBe(" 10px"); +}); diff --git a/test/configCases/css/import-different-case/style-imported.css b/test/configCases/css/import-different-case/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/import-different-case/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/import-different-case/style.css b/test/configCases/css/import-different-case/style.css new file mode 100644 index 00000000000..602ea2d5aa8 --- /dev/null +++ b/test/configCases/css/import-different-case/style.css @@ -0,0 +1,4 @@ +@IMPORT "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/import-different-case/test.config.js b/test/configCases/css/import-different-case/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/import-different-case/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/import-different-case/webpack.config.js b/test/configCases/css/import-different-case/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/import-different-case/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/urls/spacing.css b/test/configCases/css/urls/spacing.css index 424db230184..21f5c3e982a 100644 --- a/test/configCases/css/urls/spacing.css +++ b/test/configCases/css/urls/spacing.css @@ -47,3 +47,11 @@ spacing { spacing { l: green url(/img.png) xyz; } + +spacing { + m: green URL(/img.png) xyz; +} + +spacing { + n: green uRl(/img.png) xyz; +}