globalCss = updater.getOutput()
+ .get(updater.generatedFlowImports).stream()
+ .filter(globalCssImporter).map(line -> {
+ Matcher matcher = injectGlobalCssPattern.matcher(line);
+ matcher.find();
+ return matcher.group(1);
+ }).collect(Collectors.toList());
+
+ assertTrue("Import for web-components should also inject global CSS",
+ updater.webComponentImports.stream()
+ .anyMatch(globalCssImporter));
+
+ assertTrue(
+ "Should contain function to import global CSS into embedded component",
+ updater.webComponentImports.stream().anyMatch(line -> line
+ .contains("import { injectGlobalWebcomponentCss }")));
+ globalCss.forEach(css -> assertTrue(
+ "Should register global CSS " + css + " for webcomponent",
+ updater.webComponentImports.stream()
+ .anyMatch(line -> line.contains(
+ "injectGlobalWebcomponentCss(" + css + ");"))));
+
+ }
+
@Test
public void jsModulesOrderIsPreservedAnsAfterJsModules() {
updater.run();
diff --git a/flow-server/src/test/java/com/vaadin/flow/server/frontend/UpdateImportsWithByteCodeScannerTest.java b/flow-server/src/test/java/com/vaadin/flow/server/frontend/UpdateImportsWithByteCodeScannerTest.java
index d9adeda4a5e..daac37dd925 100644
--- a/flow-server/src/test/java/com/vaadin/flow/server/frontend/UpdateImportsWithByteCodeScannerTest.java
+++ b/flow-server/src/test/java/com/vaadin/flow/server/frontend/UpdateImportsWithByteCodeScannerTest.java
@@ -317,6 +317,7 @@ public void cssInLazyChunkWorks() throws Exception {
assertOnce("import { injectGlobalCss } from", chunkLines);
assertOnce("from 'Frontend/foo.css?inline';", chunkLines);
assertOnce("import $cssFromFile_0 from", chunkLines);
+ assertOnce("injectGlobalCss($cssFromFile_0", chunkLines);
// assert lines order is preserved
Assert.assertEquals(
diff --git a/flow-tests/test-embedding/test-embedding-application-theme/frontend/css-import-component.css b/flow-tests/test-embedding/test-embedding-application-theme/frontend/css-import-component.css
new file mode 100644
index 00000000000..60394390016
--- /dev/null
+++ b/flow-tests/test-embedding/test-embedding-application-theme/frontend/css-import-component.css
@@ -0,0 +1,3 @@
+DIV.cssimport {
+ color: gold
+}
diff --git a/flow-tests/test-embedding/test-embedding-application-theme/frontend/themes/embedded-theme/theme.json b/flow-tests/test-embedding/test-embedding-application-theme/frontend/themes/embedded-theme/theme.json
index 12898b8b6dc..3479a8c1278 100644
--- a/flow-tests/test-embedding/test-embedding-application-theme/frontend/themes/embedded-theme/theme.json
+++ b/flow-tests/test-embedding/test-embedding-application-theme/frontend/themes/embedded-theme/theme.json
@@ -1,4 +1,5 @@
{
+ "autoInjectGlobalCssImports": true,
"documentCss": ["@fortawesome/fontawesome-free/css/all.css"],
"assets": {
"@fortawesome/fontawesome-free": {
diff --git a/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/CssImportComponent.java b/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/CssImportComponent.java
new file mode 100644
index 00000000000..235307a3471
--- /dev/null
+++ b/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/CssImportComponent.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2024 Vaadin Ltd.
+ *
+ * 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.
+ */
+
+package com.vaadin.flow.webcomponent;
+
+import com.vaadin.flow.component.Tag;
+import com.vaadin.flow.component.dependency.CssImport;
+import com.vaadin.flow.component.html.Div;
+
+@Tag("css-import-component")
+@CssImport("./css-import-component.css")
+public class CssImportComponent extends Div {
+
+ public CssImportComponent(String id) {
+ setId(id);
+ Div div = new Div(
+ "Global CssImport styles should be applied inside embedded web component, this should not be black");
+ div.setClassName("cssimport");
+ add(div);
+ }
+}
diff --git a/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/ThemedComponent.java b/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/ThemedComponent.java
index 25c08426c90..507401aaf29 100644
--- a/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/ThemedComponent.java
+++ b/flow-tests/test-embedding/test-embedding-application-theme/src/main/java/com/vaadin/flow/webcomponent/ThemedComponent.java
@@ -18,7 +18,6 @@
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
-
import com.vaadin.flow.uitest.ui.dependencies.TestVersion;
@NpmPackage(value = "@fortawesome/fontawesome-free", version = TestVersion.FONTAWESOME)
@@ -27,6 +26,7 @@ public class ThemedComponent extends Div {
public static final String TEST_TEXT_ID = "test-text";
public static final String MY_COMPONENT_ID = "field";
+ public static final String CSS_IMPORT_COMPONENT_ID = "embedded-cssimport";
public static final String EMBEDDED_ID = "embedded";
public static final String HAND_ID = "sparkle-hand";
@@ -45,5 +45,6 @@ public ThemedComponent() {
add(new Div());
add(new MyComponent().withId(MY_COMPONENT_ID));
+ add(new CssImportComponent(CSS_IMPORT_COMPONENT_ID));
}
}
diff --git a/flow-tests/test-embedding/test-embedding-application-theme/src/main/webapp/index.html b/flow-tests/test-embedding/test-embedding-application-theme/src/main/webapp/index.html
index a9dbc13515c..45f81992bdc 100644
--- a/flow-tests/test-embedding/test-embedding-application-theme/src/main/webapp/index.html
+++ b/flow-tests/test-embedding/test-embedding-application-theme/src/main/webapp/index.html
@@ -1,17 +1,20 @@
-
-
-
-
-
-
-
- Lumo styles should not be applied
- Internal should not apply, this should be black
- Document styles should apply, this should be blue
-
-
-
-
-
-
+
+
+
+
+
+ Lumo styles should not be applied
+
+ Internal should not apply, this should be black
+
+
+ CssImport styles should apply, this should not be black
+
+
+ Document styles should apply, this should be blue
+
+
+
+
+
diff --git a/flow-tests/test-embedding/test-embedding-application-theme/src/test/java/com/vaadin/flow/webcomponent/ApplicationThemeComponentIT.java b/flow-tests/test-embedding/test-embedding-application-theme/src/test/java/com/vaadin/flow/webcomponent/ApplicationThemeComponentIT.java
index a8b403c61cf..94c9bfb6f53 100644
--- a/flow-tests/test-embedding/test-embedding-application-theme/src/test/java/com/vaadin/flow/webcomponent/ApplicationThemeComponentIT.java
+++ b/flow-tests/test-embedding/test-embedding-application-theme/src/test/java/com/vaadin/flow/webcomponent/ApplicationThemeComponentIT.java
@@ -18,6 +18,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.testbench.DivElement;
import com.vaadin.flow.component.html.testbench.H1Element;
import com.vaadin.flow.component.html.testbench.SpanElement;
@@ -103,6 +104,14 @@ private void validateEmbeddedComponent(TestBenchElement themedComponent,
Assert.assertEquals("Color should have been applied",
"rgba(0, 128, 0, 1)", handElement.getCssValue("color"));
+
+ // Ensure @CssImport styles are applied
+ final WebElement cssImportElement = embeddedComponent
+ .$("css-import-component").first().$(DivElement.class).first();
+ Assert.assertEquals(
+ "Color fom CSSImport annotation should have been applied",
+ "rgba(255, 215, 0, 1)", cssImportElement.getCssValue("color"));
+
}
@Test
@@ -223,8 +232,8 @@ public void multipleSameEmbedded_cssTargetingDocumentShouldOnlyAddElementsOneTim
2l, getCommandExecutor().executeScript(
"return document.head.querySelectorAll('link[rel=stylesheet][href^=\"https://fonts.googleapis.com\"]').length"));
Assert.assertEquals(
- "Project contains 2 css injections to document and both should be hashed",
- 2l, getCommandExecutor().executeScript(
+ "Project contains 3 css injections to document and all should be hashed",
+ 3l, getCommandExecutor().executeScript(
"return window.Vaadin.theme.injectedGlobalCss.length"));
}
@@ -246,4 +255,22 @@ public void lumoImports_doNotLeakEmbeddingPage() {
"rgba(0, 0, 0, 1)", element.getCssValue("color"));
}
+
+ @Test
+ public void cssImportAnnotation_applyToEmbeddingPage() {
+ open();
+ checkLogsForErrors();
+
+ // Ensure embedded components are loaded before testing embedding page
+ validateEmbeddedComponent($("themed-component").id("first"), "first");
+ validateEmbeddedComponent($("themed-component").id("second"), "second");
+
+ final DivElement element = $(DivElement.class)
+ .attribute("id", "cssimport").waitForFirst();
+ Assert.assertEquals(
+ "CssImport styles (colors) should have been applied to elements in embedding page",
+ "rgba(255, 215, 0, 1)", element.getCssValue("color"));
+
+ }
+
}