Skip to content

Commit

Permalink
Update branch (#7231)
Browse files Browse the repository at this point in the history
* Avoid clean up if PNPM is used (#7095)

Fixes #7083

* Iterate over a copy for UI internals listeners (#7103)

Avoids ConcurrentModificationException if firing an event causes
listeners to be added or removed.

* Convert lambda exps to simple loops to fix Java 11 build (#7102)

* Fix command expectations to expect a local install (#7100)

Test run against a local installation of pnpm
test was expecting a global installation
to be used.

* Highlight drop target when dragged on child

Fixes #7108

..but does not fix case where child is a drop target too and drag moves
back to parent drop target -> the class name for parent element is not reapplied.

* Make nested drop target highlighting work

Fixes #7109

* Allow adding a local js module through Page.addJsModule (#6933)

* Deny adding a local js module through Page.addJsModule

* Deprecate Page.addJsModule(url, loadMode)

* Remove old "flow-deps" dependency/package-lock if PNPM is used (#7117)

Part of #7113

* Fix using host value from the request (#7115)

When using the host value from the request header
we need to add the transport as
host only contains the server and port.

In the off case that we get the scheme
as a header we should use that.

* Exclude pnpm from managing itself (#7125)

* Use recommended API to get chrome capabilities (#7138)

DesiredCapabilities.chrome will be deprecated and removed.
Current usage results in logged warnings "Using `new ChromeOptions()` is preferred to `DesiredCapabilities.chrome()`"
https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/client/src/org/openqa/selenium/remote/DesiredCapabilities.java#L115-L118

* Add explicit "crossorigin" attribute to bundle script tag in bootstrap (#7124)

* Use Element API for traversing children to call the onEnabledStateChanged method (#7131)

Fixes #7085

* Deprecate isIOS method and make it in ExtendedClientDetails (#7139)

Fixes #6671

* Added missing constructor with scanNestedDefinitions option (#7099)

Cherry pick from: vaadin/framework#11801

* Upgrade webpack plugins to fix npm audit warnings (#7122)

Upgrade compression-webpack-plugin dependency
Upgrade copy-webpack-plugin version
Upgrade webpack dependencies versions

* Only sending to server should be postponed


- Update value in StateTree on the client side immediately
- Defer execution only sending a new value to the server

Fixes #7128

* Add IT test

* Remove IT test which doesn't reproduce the issue

* Handle possible array (#7159)

If building sourcemaps for webpack
the assets array will contain an array
of bundles instead of a single string.

Fixes #7158

* Workarounds for Safari 10  <script nomodule> and scope bugs (#7165)

* Unregister listener when disconnecting web component (#7061)

* Make links focusable (#7155)

* Fix broken mobile dnd polyfill for ipad on iOS13

Fixes #7123

* Copy when jar (#7175)

If packaging the project as
a jar then we will copy the
frontend files during prepare-frontend.

This way running the development
mode jar should have all frontend
files available.

Fixes #6994

* Fix running pnpm for a local installation (#7185)

* Fix ElementStateProvider serialization (#7192)

Add readResolve method for singleton class handing
during (de)serialization of state providers.

Fixes #7190

* Pin pnpm verion to 4.5 and remove workaround for 4.3.3 (#7191)

Fixes #7183

* Pass query parameters to the new location (#7189)

* Update chromedriver to v79 (#7181)

* Assert chrome version 79 (#7201)

* Only clear all if value changes. (#7212)

If we remove all when the innerHTML
value stays the same we will loose the innerHTML
on the client as the value is not re-sent,
but is still cleared from the client.

Fixes #4644

* Don't add abstract error targets (#7215)

Filter out any abstract classes from
error navigation targets as they can't
be instantiated anyway.

Fixes vaadin/spring#530

* Add onclick to error window (#7217)

Now the webpack error window
can be closed by clicking it.

Fixes #7211

* Error message for failing imports should be tool dependent (#7216)

Fixes #7182

* Combine all constructors together

Fixes #7148

* log: debug the list of dependencies and imports found in classes (#7221)

Co-authored-by: Denis <denis@vaadin.com>
Co-authored-by: Leif Åstrand <legioth@gmail.com>
Co-authored-by: Mehdi Javan <32511762+mehdi-vaadin@users.noreply.github.com>
Co-authored-by: caalador <mikael.grankvist@gmail.com>
Co-authored-by: Pekka Hyvönen <pekka@vaadin.com>
Co-authored-by: Bogdan Udrescu <bogdanudrescu@users.noreply.github.com>
Co-authored-by: Guille <alvarezguille@users.noreply.github.com>
Co-authored-by: Johannes Eriksson <joheriks@vaadin.com>
Co-authored-by: Serhii Kulykov <iamkulykov@gmail.com>
Co-authored-by: Muammer Yucel <muammer.yucel.82@gmail.com>
Co-authored-by: Giovanni Lovato <giovanni@lova.to>
Co-authored-by: Manuel Carrasco Moñino <manolo@apache.org>
  • Loading branch information
13 people authored Dec 27, 2019
1 parent a2ee97a commit d5bdbf0
Show file tree
Hide file tree
Showing 58 changed files with 1,372 additions and 373 deletions.
18 changes: 9 additions & 9 deletions drivers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@
<root>
<windows>
<driver id="googlechrome">
<version id="78.0.3904.70">
<version id="79.0.3945.36">
<bitrate thirtytwobit="true" sixtyfourbit="true">
<filelocation>https://chromedriver.storage.googleapis.com/78.0.3904.70/chromedriver_win32.zip</filelocation>
<hash>26705e683632c6e1f9c62179b6143b409f4d7681</hash>
<filelocation>https://chromedriver.storage.googleapis.com/79.0.3945.36/chromedriver_win32.zip</filelocation>
<hash>671dafdf4380e1194268f72278f6c0324f47ae8e</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
</windows>
<linux>
<driver id="googlechrome">
<version id="78.0.3904.70">
<version id="79.0.3945.36">
<bitrate sixtyfourbit="true">
<filelocation>https://chromedriver.storage.googleapis.com/78.0.3904.70/chromedriver_linux64.zip</filelocation>
<hash>63e13e5f0df96af1cc3a2006c00b2f1871b62caf</hash>
<filelocation>https://chromedriver.storage.googleapis.com/79.0.3945.36/chromedriver_linux64.zip</filelocation>
<hash>3cf7d35a154ad53c7df627ad8d33d70dc941e658</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
</linux>
<osx>
<driver id="googlechrome">
<version id="78.0.3904.70">
<version id="79.0.3945.36">
<bitrate sixtyfourbit="true">
<filelocation>https://chromedriver.storage.googleapis.com/78.0.3904.70/chromedriver_mac64.zip</filelocation>
<hash>ce06a7d3a9d18b3d054d3b4c3c32d2cd74e81a91</hash>
<filelocation>https://chromedriver.storage.googleapis.com/79.0.3945.36/chromedriver_mac64.zip</filelocation>
<hash>a6009cbaadc86cab54982195bb760c64e926cf59</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1266,9 +1266,12 @@ private void handleDomEvent(Event event, BindingContext context) {
}
}

JsArray<Runnable> commands = JsCollections.array();
synchronizeProperties.forEach(
name -> commands.push(getSyncPropertyCommand(name, context)));

Consumer<String> sendCommand = debouncePhase -> {
synchronizeProperties
.forEach(name -> syncPropertyIfNeeded(name, context));
commands.forEach(Runnable::run);

sendEventToServer(node, type, eventData, debouncePhase);
};
Expand All @@ -1282,6 +1285,13 @@ private void handleDomEvent(Event event, BindingContext context) {
}
}

private Runnable getSyncPropertyCommand(String propertyName,
BindingContext context) {
return context.node.getMap(NodeFeatures.ELEMENT_PROPERTIES)
.getProperty(propertyName).getSyncToServerCommand(WidgetUtil
.getJsProperty(context.htmlNode, propertyName));
}

private static void sendEventToServer(StateNode node, String type,
JsonObject eventData, String debouncePhase) {
if (debouncePhase == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public class MapProperty implements ReactiveValue {
*/
private boolean isServerUpdate;

private static final Runnable NO_OP = () -> {
};

private final ReactiveEventRouter<MapPropertyChangeListener, MapPropertyChangeEvent> eventRouter = new ReactiveEventRouter<MapPropertyChangeListener, MapPropertyChangeEvent>(
this) {
@Override
Expand Down Expand Up @@ -262,8 +265,20 @@ public String getValueOrDefault(String defaultValue) {
*
* @param newValue
* the new value to set.
* @see #getSyncToServerCommand(Object)
*/
public void syncToServer(Object newValue) {
getSyncToServerCommand(newValue).run();
}

/**
* Sets the value of this property and returns a synch to server command.
*
* @param newValue
* the new value to set.
* @see #syncToServer(Object)
*/
public Runnable getSyncToServerCommand(Object newValue) {
Object currentValue = hasValue() ? getValue() : null;

if (Objects.equals(newValue, currentValue)) {
Expand All @@ -282,7 +297,7 @@ public void syncToServer(Object newValue) {
if (tree.isActive(node)) {
doSetValue(newValue);

tree.sendNodePropertySyncToServer(this);
return () -> tree.sendNodePropertySyncToServer(this);
} else {
/*
* Fire an fake event to reset the property value back in the
Expand All @@ -297,5 +312,6 @@ public void syncToServer(Object newValue) {
Reactive.flush();
}
}
return NO_OP;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,25 @@ public class BeanValidationBinder<BEAN> extends Binder<BEAN> {
* the bean type to use, not <code>null</code>
*/
public BeanValidationBinder(Class<BEAN> beanType) {
super(beanType);
this(beanType,false);
}

/**
* Creates a new binder that uses reflection based on the provided bean type
* to resolve bean properties. It assumes that JSR-303 bean validation
* implementation is present on the classpath. If there is no such
* implementation available then {@link Binder} class should be used instead
* (this constructor will throw an exception). Otherwise
* {@link BeanValidator} is added to each binding that is defined using a
* property name.
*
* @param beanType
* the bean type to use, not {@code null}
* @param scanNestedDefinitions
* if {@code true}, scan for nested property definitions as well
*/
public BeanValidationBinder(Class<BEAN> beanType, boolean scanNestedDefinitions) {
super(beanType, scanNestedDefinitions);
if (!BeanUtil.checkBeanValidationAvailable()) {
throw new IllegalStateException(
BeanValidationBinder.class.getSimpleName()
Expand Down
28 changes: 14 additions & 14 deletions flow-data/src/main/java/com/vaadin/flow/data/binder/Binder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,20 @@ public Binder() {
});
}

/**
* Creates a new binder that uses reflection based on the provided bean type
* to resolve bean properties.
*
* @param beanType
* the bean type to use, not {@code null}
* @param scanNestedDefinitions
* if {@code true}, scan for nested property definitions as well
*/
public Binder(Class<BEAN> beanType, boolean scanNestedDefinitions) {
this(BeanPropertySet.get(beanType, scanNestedDefinitions,
PropertyFilterDefinition.getDefaultFilter()));
}

/**
* Creates a binder using a custom {@link PropertySet} implementation for
* finding and resolving property names for
Expand Down Expand Up @@ -1510,20 +1524,6 @@ protected void handleFieldValueChange(Binding<BEAN, ?> binding) {
}
}

/**
* Creates a new binder that uses reflection based on the provided bean type
* to resolve bean properties.
*
* @param beanType
* the bean type to use, not {@code null}
* @param scanNestedDefinitions
* if {@code true}, scan for nested property definitions as well
*/
public Binder(Class<BEAN> beanType, boolean scanNestedDefinitions) {
this(BeanPropertySet.get(beanType, scanNestedDefinitions,
PropertyFilterDefinition.getDefaultFilter()));
}

/**
* Returns the bean that has been bound with {@link #bind}, or null if a
* bean is not currently bound.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.vaadin.flow.component.dnd.DropTarget;
import com.vaadin.flow.internal.UsageStatistics;
import com.vaadin.flow.server.Command;
import com.vaadin.flow.server.WebBrowser;
import com.vaadin.flow.shared.Registration;
import com.vaadin.flow.shared.ui.LoadMode;

Expand Down Expand Up @@ -83,6 +84,26 @@ public class DndUtil {
*/
private static final String DETACH_LISTENER_FOR_DROP_TARGET = "_detachListenerForDropTarget";

// package protected for unit test
//@formatter:off
static final String MOBILE_POLYFILL_INJECT_SCRIPT =
"if ((/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)"
+ "|| (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) {"
+ "var script1 = document.createElement('script');"
+ "var script2 = document.createElement('script');"
+ "script1.async = false;"
+ "script2.async = false;"
+ "script1.src = \"%1$s\";"
+ "script2.src = \"%2$s\";"
+ "window.Vaadin.__forceApplyMobileDragDrop = true;"
+ "document.head.appendChild(script1);"
+ "document.head.appendChild(script2);}";
//@formatter:on

private static final String DND_POLYFILL_SCRIPT_KEY = "DND-POLYFILL-SCRIPT";
private static final String MOBILE_DND_POLYFILL_URL = "context://webjars/mobile-drag-drop/2.3.0-rc.1/index.min.js";
private static final String VAADIN_MOBILE_DND_POLYFILL_URL = "context://webjars/vaadin__vaadin-mobile-drag-drop/1.0.0/index.min.js";

private DndUtil() {
// no instances from this class
}
Expand Down Expand Up @@ -120,12 +141,22 @@ public static void addDndConnectorWhenComponentAttached(
*/
public static void addMobileDndPolyfillIfNeeded(Component component) {
component.getElement().getNode().runWhenAttached(ui -> {
if (ui.getSession().getBrowser().isIOS()) {
ui.getPage().addJavaScript(
"context://webjars/mobile-drag-drop/2.3.0-rc.1/index.min.js");
ui.getPage().addJavaScript(
"context://webjars/vaadin__vaadin-mobile-drag-drop/1.0.0/index.min.js");
if (ComponentUtil.getData(ui, DND_POLYFILL_SCRIPT_KEY) != null) {
return;
}
// #7123 need to delegate iOS checking to client side due to iPads
// with iOS 13
WebBrowser browser = ui.getSession().getBrowser();
String url1 = ui.getSession().getService().resolveResource(
MOBILE_DND_POLYFILL_URL,
browser);
String url2 = ui.getSession().getService().resolveResource(
VAADIN_MOBILE_DND_POLYFILL_URL,
browser);

ui.getPage().executeJs(
String.format(MOBILE_POLYFILL_INJECT_SCRIPT, url1, url2));
ComponentUtil.setData(ui, DND_POLYFILL_SCRIPT_KEY, true);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@ window.Vaadin.Flow.dndConnector = {
if (effect) {
event.dataTransfer.dropEffect = effect;
}

if (effect && effect !== 'none') {
event.currentTarget.classList.add("v-drag-over-target");
/* #7108: if drag moves on top of drop target's children, first another ondragenter event
* is fired and then a ondragleave event. This happens again once the drag
* moves on top of another children, or back on top of the drop target element.
* Thus need to "cancel" the following ondragleave, to not remove class name.
* Drop event will happen even when dropped to a child element. */
if (event.currentTarget.classList.contains("v-drag-over-target")) {
event.currentTarget['__skip-leave'] = true;
} else {
event.currentTarget.classList.add("v-drag-over-target");
}
// enables browser specific pseudo classes (at least FF)
event.preventDefault();
event.stopPropagation(); // don't let parents know
Expand All @@ -30,7 +40,14 @@ window.Vaadin.Flow.dndConnector = {
},

__ondragleaveListener: function (event) {
event.currentTarget.classList.remove("v-drag-over-target");
if (event.currentTarget['__skip-leave']) {
event.currentTarget['__skip-leave'] = false;
} else {
event.currentTarget.classList.remove("v-drag-over-target");
}
// #7109 need to stop or any parent drop target might not get highlighted,
// as ondragenter for it is fired before the child gets dragleave.
event.stopPropagation();
},

__ondropListener: function (event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
package com.vaadin.flow.component.dnd;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.dnd.internal.DnDUtilHelper;
import com.vaadin.flow.component.internal.DependencyList;
import com.vaadin.flow.component.internal.PendingJavaScriptInvocation;
import com.vaadin.flow.internal.UsageStatistics;
import com.vaadin.flow.router.RouterLink;
import com.vaadin.flow.server.DefaultDeploymentConfiguration;
import com.vaadin.flow.server.VaadinService;
import com.vaadin.flow.server.VaadinServlet;
import com.vaadin.flow.server.VaadinSession;
import com.vaadin.flow.server.WebBrowser;
Expand Down Expand Up @@ -52,9 +55,14 @@ public boolean isCompatibilityMode() {
WebBrowser browser = Mockito.mock(WebBrowser.class);
Mockito.when(browser.isIOS()).then(invocation -> iOS);

VaadinService service = Mockito.mock(VaadinService.class);
Mockito.when(service.resolveResource(Mockito.anyString(),
Mockito.any(WebBrowser.class))).thenReturn("");

VaadinSession session = Mockito.mock(VaadinSession.class);
Mockito.when(session.getConfiguration()).thenReturn(configuration);
Mockito.when(session.getBrowser()).thenReturn(browser);
Mockito.when(session.getService()).thenReturn(service);

ui = new MockUI(session);
}
Expand Down Expand Up @@ -106,31 +114,26 @@ public void testExtension_staticApiNotIosNotCompatibilityMode_connectorDependenc
}

@Test
public void testExtension_iOS_mobileDnDpolyfillLoaded() {
public void testExtension_iOS_mobileDnDpolyfillScriptInjected() {
iOS = true;
ui.getInternals().getDependencyList().clearPendingSendToClient();
ui.getInternals().dumpPendingJavaScriptInvocations();

RouterLink component = new RouterLink();
ui.add(component);
runStaticCreateMethodForExtension(component);

DependencyList dependencyList = ui.getInternals().getDependencyList();
Collection<Dependency> pendingSendToClient = dependencyList
.getPendingSendToClient();
List<PendingJavaScriptInvocation> pendingJavaScriptInvocations = ui
.getInternals().dumpPendingJavaScriptInvocations();

Assert.assertEquals("No dependency added", 2,
pendingSendToClient.size());

Iterator<Dependency> iterator = pendingSendToClient.iterator();
Dependency dependency = iterator.next();
Assert.assertEquals("Wrong dependency loaded",
"context://webjars/mobile-drag-drop/2.3.0-rc.1/index.min.js",
dependency.getUrl());
dependency = iterator.next();
Assert.assertEquals("Wrong dependency loaded",
"context://webjars/vaadin__vaadin-mobile-drag-drop/1.0.0/index.min.js",
dependency.getUrl());
Assert.assertEquals(1, pendingJavaScriptInvocations.size());

PendingJavaScriptInvocation pendingJavaScriptInvocation = pendingJavaScriptInvocations
.get(0);
// the urls are switched to "" by the mocked service method
String fake = String.format(DnDUtilHelper.MOBILE_DND_INJECT_SCRIPT, "",
"");
Assert.assertEquals(fake,
pendingJavaScriptInvocation.getInvocation().getExpression());
}

protected abstract void runStaticCreateMethodForExtension(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2019 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.component.dnd.internal;

public class DnDUtilHelper {

public static final String MOBILE_DND_INJECT_SCRIPT = DndUtil.MOBILE_POLYFILL_INJECT_SCRIPT;

private DnDUtilHelper() {
// sonarqube
}
}
Loading

0 comments on commit d5bdbf0

Please sign in to comment.