Skip to content

Commit

Permalink
Merge branch 'main' into fix/18672-unsupported-feature-flags
Browse files Browse the repository at this point in the history
  • Loading branch information
mshabarov committed May 2, 2024
2 parents cf47231 + 63e6dfd commit b320073
Show file tree
Hide file tree
Showing 33 changed files with 395 additions and 236 deletions.
2 changes: 1 addition & 1 deletion flow-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.16.1</version>
<version>1.17.0</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2613,8 +2613,7 @@ public void readBean_converterThrows_exceptionHandlerSet_bindingExceptionIsThrow
throw new NullPointerException();
}, name -> name))
.bind(Person::getFirstName, Person::setFirstName)
.read(new Person());

.read(Person.createTestPerson1());
}

@Test(expected = BindingException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ export abstract class ReactAdapterElement extends HTMLElement {
protected useCustomEvent<T = undefined>(type: string, options: CustomEventInit<T> = {}): DispatchEvent<T> {
if (!this.#customEvents.has(type)) {
const dispatch = ((detail?: T) => {
const eventInitDict = "detail" in options ? {
const eventInitDict = detail === undefined ? options : {
...options,
detail
} : options;
};
const event = new CustomEvent(type, eventInitDict);
return this.dispatchEvent(event);
}) as DispatchEvent<T>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public boolean hasProperty(String name) {
* the name of the property to remove
*/
public void removeProperty(String name) {
super.remove(name);
remove(name);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ protected Serializable remove(String key) {
Serializable oldValue = super.remove(key);

fireEvent(new PropertyChangeEvent(Element.get(getNode()), key, oldValue,
true));
false));

return oldValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,12 @@ public class InitParameters implements Serializable {
* Configuration name for cleaning or leaving frontend files in build.
*/
public static final String CLEAN_BUILD_FRONTEND_FILES = "vaadin.clean.build.frontend.files";

/**
* Configuration name for how long since last browser open before we open a
* new tab for the application in development mode.
*
* Time is given in minutes.
*/
public static final String LAUNCH_BROWSER_DELAY = "launch-browser-delay";
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ abstract class AbstractUpdateImports implements Runnable {
+ " return !ae || ae.blur() || ae.focus() || true;\n" + "}";
private static final String IMPORT_TEMPLATE = "import '%s';";
private static final Pattern STARTING_DOT_SLASH = Pattern.compile("^\\./+");
private static final Pattern VAADIN_LUMO_GLOBAL_IMPORT = Pattern
.compile(".*@vaadin/vaadin-lumo-styles/.*-global.js.*");
final Options options;

private final UnaryOperator<String> themeToLocalPathConverter;
Expand All @@ -106,7 +108,8 @@ abstract class AbstractUpdateImports implements Runnable {

private ClassFinder classFinder;

private final File generatedFlowImports;
final File generatedFlowImports;
final File generatedFlowWebComponentImports;
private final File generatedFlowDefinitions;
private File chunkFolder;

Expand All @@ -131,6 +134,10 @@ abstract class AbstractUpdateImports implements Runnable {
generatedFlowDefinitions = new File(
generatedFlowImports.getParentFile(),
FrontendUtils.IMPORTS_D_TS_NAME);

generatedFlowWebComponentImports = FrontendUtils
.getFlowGeneratedWebComponentsImports(
options.getFrontendDirectory());
this.chunkFolder = new File(generatedFlowImports.getParentFile(),
"chunks");

Expand All @@ -146,6 +153,8 @@ public void run() {

Map<File, List<String>> output = process(css, javascript);
writeOutput(output);
writeWebComponentImports(
filterWebComponentImports(output.get(generatedFlowImports)));

getLogger().debug("Imports and chunks update took {} ms.",
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
Expand Down Expand Up @@ -207,6 +216,30 @@ protected void writeOutput(Map<File, List<String>> outputFiles) {
}
}

// Visible for test
List<String> filterWebComponentImports(List<String> lines) {
if (lines != null) {
// Exclude Lumo global imports for exported web-component
return lines.stream()
.filter(VAADIN_LUMO_GLOBAL_IMPORT.asPredicate().negate())
.collect(Collectors.toList());
}
return lines;
}

private void writeWebComponentImports(List<String> lines) {
if (lines != null) {
try {
generatedFilesSupport.writeIfChanged(
generatedFlowWebComponentImports, lines);
} catch (IOException e) {
throw new IllegalStateException(
"Failed to update the generated Flow imports for exported web component",
e);
}
}
}

/**
* Processes what the scanner found and produces a set of files to write to
* the generated folder.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ public class FrontendUtils {
*/
public static final String IMPORTS_D_TS_NAME = "generated-flow-imports.d.ts";

/**
* Name of the file that contains application imports, javascript, theme and
* style annotations used when embedding Flow as web-component.
*/
public static final String IMPORTS_WEB_COMPONENT_NAME = "generated-flow-webcomponent-imports.js";

public static final String THEME_IMPORTS_D_TS_NAME = "theme.d.ts";
public static final String THEME_IMPORTS_NAME = "theme.js";

Expand Down Expand Up @@ -1221,6 +1227,21 @@ public static File getFlowGeneratedImports(File frontendFolder) {
return new File(getFlowGeneratedFolder(frontendFolder), IMPORTS_NAME);
}

/**
* Gets the location of the generated import file for exported web
* components.
*
* @param frontendFolder
* the project frontend folder
* @return the location of the generated import JS file for exported web
* components
*/
public static File getFlowGeneratedWebComponentsImports(
File frontendFolder) {
return new File(getFlowGeneratedFolder(frontendFolder),
IMPORTS_WEB_COMPONENT_NAME);
}

/**
* Gets the folder where exported web components are generated.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ function build() {
""";

private static final String FLOW_TSX = "Flow.tsx";
private static final String REACT_ADAPTER_TEMPLATE = "ReactAdapter.template";
private static final String REACT_ADAPTER_TSX = "ReactAdapter.tsx";
static final String FLOW_FLOW_TSX = "flow/" + FLOW_TSX;
static final String FLOW_REACT_ADAPTER_TSX = "flow/" + REACT_ADAPTER_TSX;
Expand Down Expand Up @@ -151,8 +152,9 @@ private void doExecute() throws ExecutionFailedException {
frontendGeneratedFolder, FrontendUtils.ROUTES_TSX);
try {
writeFile(flowTsx, getFlowTsxFileContent(routesTsx.exists()));
if (fileAvailable(REACT_ADAPTER_TSX)) {
writeFile(reactAdapterTsx, getFileContent(REACT_ADAPTER_TSX));
if (fileAvailable(REACT_ADAPTER_TEMPLATE)) {
writeFile(reactAdapterTsx,
getFileContent(REACT_ADAPTER_TEMPLATE));
}
if (!routesTsx.exists()) {
boolean isHillaUsed = FrontendUtils.isHillaUsed(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public class TaskGenerateWebComponentBootstrap
protected String getFileContent() {
List<String> lines = new ArrayList<>();

lines.add(
"import 'Frontend/generated/flow/generated-flow-imports.js';");
lines.add("import 'Frontend/generated/flow/"
+ FrontendUtils.IMPORTS_WEB_COMPONENT_NAME + "';");
lines.add("import { init } from '" + FrontendUtils.JAR_RESOURCES_IMPORT
+ "FlowClient.js';");
lines.add("init();");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.vaadin.flow.server.frontend;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.FileVisitResult;
Expand Down Expand Up @@ -54,11 +55,13 @@ public class TaskRemoveOldFrontendGeneratedFiles implements FallibleCommand {
private static final Logger LOGGER = LoggerFactory
.getLogger(TaskRemoveOldFrontendGeneratedFiles.class);
private final Path frontendGeneratedFolder;
private final File frontendFolder;

private final Set<Path> existingFiles = new HashSet<>();
private GeneratedFilesSupport generatedFilesSupport;

public TaskRemoveOldFrontendGeneratedFiles(Options options) {
frontendFolder = options.getFrontendDirectory();
frontendGeneratedFolder = options.getFrontendGeneratedFolder().toPath();
if (frontendGeneratedFolder.toFile().exists()) {
try (Stream<Path> files = Files.walk(frontendGeneratedFolder)) {
Expand Down Expand Up @@ -123,10 +126,13 @@ public FileVisitResult postVisitDirectory(Path dir,

private Predicate<Path> isKnownUnhandledFile() {
Path flowGeneratedImports = FrontendUtils
.getFlowGeneratedImports(
frontendGeneratedFolder.getParent().toFile())
.toPath().toAbsolutePath();
.getFlowGeneratedImports(frontendFolder).toPath()
.toAbsolutePath();
Path flowGeneratedWebComponentImports = FrontendUtils
.getFlowGeneratedWebComponentsImports(frontendFolder).toPath()
.toAbsolutePath();
return path -> path.equals(flowGeneratedImports)
|| path.equals(flowGeneratedWebComponentImports)
|| path.equals(flowGeneratedImports
.resolveSibling(FrontendUtils.IMPORTS_D_TS_NAME))
|| path.getFileName().toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ export function fireRouterEvent(type, detail) {
// @ts-ignore
function vaadinRouterGlobalClickHandler(event) {
// ignore the click if the default action is prevented
if (event.defaultPrevented) {
// Prevented side-nav click should be handled if targeting Flow route.
if (event.defaultPrevented &&
(event.target.tagName !== "VAADIN-SIDE-NAV-ITEM" && mountedContainer)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
"author": "",
"license": "Apache-2.0",
"dependencies": {
"react": "18.3.0",
"react-dom": "18.3.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-router-dom": "6.23.0"
},
"devDependencies": {
"@types/react": "18.3.0",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
******************************************************************************/
import { RouterConfigurationBuilder } from '@vaadin/hilla-file-router/runtime.js';
import Flow from 'Frontend/generated/flow/Flow';
import fileRoutes from 'Frontend/generated/file-routes.js';
import fileRoutes from 'Frontend/generated/file-routes';

export const { router, routes } = new RouterConfigurationBuilder()
.withFileRoutes(fileRoutes) // (1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ function writeThemeFiles(themeFolder, themeName, themeProperties, options) {
imports.push(`import { ${lumoImport} } from '@vaadin/vaadin-lumo-styles/${lumoImport}.js';\n`);
if (lumoImport === 'utility' || lumoImport === 'badge' || lumoImport === 'typography' || lumoImport === 'color') {
// Inject into main document the same way as other Lumo styles are injected
imports.push(`import '@vaadin/vaadin-lumo-styles/${lumoImport}-global.js';\n`);
// Lumo imports go to the theme global imports file to prevent style leaks
// when the theme is applied to an embedded component
globalFileContent.push(`import '@vaadin/vaadin-lumo-styles/${lumoImport}-global.js';\n`);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@
import com.vaadin.flow.dom.Element;
import com.vaadin.flow.function.SerializableRunnable;
import com.vaadin.flow.internal.JsonUtils;
import com.vaadin.flow.server.VaadinService;
import com.vaadin.flow.server.VaadinSession;
import com.vaadin.flow.server.MockServletServiceSessionSetup.TestVaadinServlet;
import com.vaadin.flow.server.MockServletServiceSessionSetup.TestVaadinServletService;
import com.vaadin.tests.PublicApiAnalyzer;
import com.vaadin.tests.util.MockUI;
Expand Down Expand Up @@ -86,9 +83,7 @@ public void stringField_basicCases() {
Assert.assertEquals("bar", field.getValue());
monitor.assertEvent(false, "foo", "bar");

// Cannot do removeProperty because
// https://github.com/vaadin/flow/issues/3994
field.getElement().setProperty("property", null);
field.getElement().removeProperty("property");
Assert.assertEquals("", field.getValue());
monitor.assertEvent(false, "bar", "");
}
Expand Down Expand Up @@ -188,6 +183,38 @@ public void stringNullField_basicCases() {
monitor.assertEvent(false, "", null);
}

@Tag("tag")
private static class StringNullFieldWithDefaultEmpty extends
AbstractSinglePropertyField<StringNullFieldWithDefaultEmpty, String> {
public StringNullFieldWithDefaultEmpty() {
super("property", "", true);
}
}

@Test
public void stringNullFieldWithDefaultEmpty_basicCases() {
StringNullFieldWithDefaultEmpty field = new StringNullFieldWithDefaultEmpty();
ValueChangeMonitor<String> monitor = new ValueChangeMonitor<>(field);

Assert.assertEquals("", field.getValue());
Assert.assertFalse(field.getElement().hasProperty("property"));
monitor.assertNoEvent();

field.setValue("foo");
Assert.assertEquals("foo", field.getValue());
monitor.assertEvent(false, "", "foo");

field.setValue("");
Assert.assertEquals("", field.getValue());
Assert.assertTrue(field.getElement().hasProperty("property"));
monitor.assertEvent(false, "foo", "");

field.setValue(null);
Assert.assertFalse(field.getElement().hasProperty("property"));
Assert.assertEquals("", field.getValue());
monitor.assertNoEvent();
}

@Tag("tag")
private static class DoubleField
extends AbstractSinglePropertyField<DoubleField, Double> {
Expand All @@ -214,9 +241,7 @@ public void doubleField_basicCases() {
Assert.assertEquals(1.1, field.getValue(), 0);
monitor.assertEvent(false, 10.1, 1.1);

// Cannot do removeProperty because
// https://github.com/vaadin/flow/issues/3994
field.getElement().setProperty("property", null);
field.getElement().removeProperty("property");
Assert.assertEquals(0.0, field.getValue(), 0);
monitor.assertEvent(false, 1.1, 0.0);
}
Expand Down Expand Up @@ -246,9 +271,7 @@ public void integerField_basicCases() {
Assert.assertEquals(1, field.getValue().intValue());
monitor.assertEvent(false, 0, 1);

// Cannot do removeProperty because
// https://github.com/vaadin/flow/issues/3994
field.getElement().setProperty("property", null);
field.getElement().removeProperty("property");
Assert.assertEquals(42, field.getValue().intValue());
monitor.assertEvent(false, 1, 42);
}
Expand Down Expand Up @@ -282,9 +305,7 @@ public void booleanField_basicCases() {
field.setValue(true);
monitor.discard();

// Cannot do removeProperty because
// https://github.com/vaadin/flow/issues/3994
field.getElement().setProperty("property", null);
field.getElement().removeProperty("property");
Assert.assertFalse(field.getValue());
monitor.assertEvent(false, true, false);
}
Expand Down Expand Up @@ -332,9 +353,7 @@ public void dateField_basicCases() {
monitor.assertEvent(false, LocalDate.of(2018, 4, 25),
LocalDate.of(2017, 3, 24));

// Cannot do removeProperty because
// https://github.com/vaadin/flow/issues/3994
field.getElement().setProperty("property", null);
field.getElement().removeProperty("property");
Assert.assertEquals(null, field.getValue());
monitor.assertEvent(false, LocalDate.of(2017, 3, 24), null);
}
Expand Down

0 comments on commit b320073

Please sign in to comment.