Skip to content

Commit

Permalink
Release 0.7.1 ready (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
vaadin-miki authored Jul 1, 2020
1 parent be67db6 commit 7c7d9eb
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 31 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This is the relevant dependency:
<dependency>
<groupId>org.vaadin.miki</groupId>
<artifactId>superfields</artifactId>
<version>0.7.0</version>
<version>0.7.1</version>
</dependency>
```

Expand Down
6 changes: 3 additions & 3 deletions demo-v14/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
<parent>
<artifactId>superfields-parent</artifactId>
<groupId>org.vaadin.miki</groupId>
<version>0.7.0</version>
<version>0.7.1</version>
</parent>

<artifactId>superfields-demo-v14</artifactId>
<version>0.7.0</version>
<version>0.7.1</version>
<name>V14 demo app for SuperFields</name>
<description>Showcase application for V14 and SuperFields.</description>
<packaging>war</packaging>
Expand All @@ -23,7 +23,7 @@
<dependency>
<groupId>org.vaadin.miki</groupId>
<artifactId>superfields</artifactId>
<version>0.7.0</version>
<version>0.7.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
Expand Down
9 changes: 7 additions & 2 deletions demo-v14/src/main/java/org/vaadin/miki/MainView.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.vaadin.flow.function.SerializableConsumer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import org.slf4j.LoggerFactory;
import org.vaadin.miki.events.text.TextSelectionNotifier;
import org.vaadin.miki.markers.CanReceiveSelectionEventsFromClient;
import org.vaadin.miki.markers.CanSelectText;
Expand Down Expand Up @@ -266,7 +267,11 @@ private void buildUnloadObserver(Component component, Consumer<Component[]> call
final Span description = new Span("This component optionally displays a browser-native window when leaving this app. Select the checkbox above and try to close the window or tab to see it in action.");
final Span counterText = new Span("There were this many attempts to leave this app so far: ");
final Span counter = new Span("0");
((UnloadObserver)component).addUnloadListener(event -> counter.setText(String.valueOf(Integer.parseInt(counter.getText())+1)));
((UnloadObserver)component).addUnloadListener(event -> {
if(event.isBecauseOfQuerying())
counter.setText(String.valueOf(Integer.parseInt(counter.getText()) + 1));
LoggerFactory.getLogger(this.getClass()).info("Unload event; attempt? {}; captured in {} and UnloadObserver is inside {}", event.isBecauseOfQuerying(), this.getClass().getSimpleName(), event.getSource().getParent().orElse(this).getClass().getSimpleName());
});

callback.accept(new Component[]{query, description, new HorizontalLayout(counterText, counter)});
}
Expand Down Expand Up @@ -336,7 +341,7 @@ public MainView() {
);
this.components.put(ObservedField.class, new ObservedField());
this.components.put(ComponentObserver.class, new ComponentObserver());
this.components.put(UnloadObserver.class, UnloadObserver.get(false));
this.components.put(UnloadObserver.class, UnloadObserver.get().withoutQueryingOnUnload());
this.components.put(ItemGrid.class, new ItemGrid<Class<? extends Component>>(
null,
() -> {
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.vaadin.miki</groupId>
<artifactId>superfields-parent</artifactId>
<version>0.7.0</version>
<version>0.7.1</version>
<modules>
<module>superfields</module>
<module>demo-v14</module>
Expand Down
2 changes: 1 addition & 1 deletion superfields/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<artifactId>superfields</artifactId>
<name>SuperFields</name>
<description>Code for various V14+ fields and other components.</description>
<version>0.7.0</version>
<version>0.7.1</version>

<properties>
<maven.compiler.source>10</maven.compiler.source>
Expand Down
8 changes: 8 additions & 0 deletions superfields/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 0.7.1 - Fixes to UnloadObserver
## New features and enhancements
* \#170 - [UnloadObserver should always send an event before unloading](https://api.github.com/repos/vaadin-miki/super-fields/issues/170)
## Changes to API
(nothing reported)
## Bug fixes
* \#178 - [UnloadObserver should belong to the UI that will be unloaded.](https://api.github.com/repos/vaadin-miki/super-fields/issues/178)

# 0.7.0 - SuperTextField
## New features and enhancements
* \#122 - [SuperTextField, SuperTextArea and text selection API](https://api.github.com/repos/vaadin-miki/super-fields/issues/122)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,31 @@

/**
* Server-side event class associated with {@code beforeunload} event happening in the client-side.
* Can optionally prompt the user before leaving the page.
* @author miki
* @since 2020-04-29
*/
public class UnloadEvent extends ComponentEvent<UnloadObserver> {

private final boolean becauseOfQuerying;

/**
* Creates a new event using the given source and indicator whether the
* event originated from the client side or the server side.
*
* @param source the source component
* @param attempted when {@code true}, the event is fired in response to querying before unloading; {@code false} otherwise.
*/
public UnloadEvent(UnloadObserver source) {
public UnloadEvent(UnloadObserver source, boolean attempted) {
super(source, true);
this.becauseOfQuerying = attempted;
}

/**
* Checks whether or not the event has been fired in response to querying the user on {@code beforeunload} browser event.
* @return {@code true} when event is in response to querying the user on {@code beforeunload}, {@code false} otherwise.
*/
public boolean isBecauseOfQuerying() {
return becauseOfQuerying;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.ComponentUtil;
import com.vaadin.flow.component.DetachEvent;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.shared.Registration;
Expand All @@ -13,36 +15,45 @@
/**
* Server-side component that listens to {@code beforeunload} events.
* Based on <a href="https://vaadin.com/forum/thread/17523194/unsaved-changes-detect-page-exit-or-reload">the code by Kaspar Scherrer and Stuart Robinson</a>.
* Warning: this class is a Singleton; the class is final, the constructors are private and there is at most one global instance.
* This component will broadcast events on {@code beforeunload} event in the browser. If {@link #isQueryingOnUnload()}
* is {@code true}, before the event the user will be prompted about leaving the page. However, there is no way to find out what the user selected.
* If {@link #isQueryingOnUnload()} is {@code false}, the event on the server will be called just before the page is unloaded.
* Note that the component must be present in the DOM structure in the browser for the event to be received on the server.
*
* @author Kaspar Scherrer, Stuart Robinson; adapted to web-component by miki
* Warning: this class is pretty much a {@link UI}-scoped singleton; the class is final, the constructors are private and there is at most one global instance per UI.
*
* @author Kaspar Scherrer, Stuart Robinson; adapted to web-component by miki; bugfixing and enhancements by Jean-François Lamy
* @since 2020-04-29
*/
@JsModule("./unload-observer.js")
@Tag("unload-observer")
public final class UnloadObserver extends PolymerTemplate<TemplateModel> implements WithIdMixin<UnloadObserver> {

private static UnloadObserver instance = null;

/**
* Returns the current instance. Will create one using default no-arg constructor if none is present yet.
* Returns or creates an instance for current UI.
* The result is associated with the UI, but not added to any of its components.
* @return An instance of {@link UnloadObserver}.
* @throws IllegalStateException if there is no current {@link UI}.
*/
public static UnloadObserver get() {
if(instance == null)
instance = new UnloadObserver();
return instance;
UI ui = UI.getCurrent();
if(ui == null)
throw new IllegalStateException("there is no UI available to create UnloadObserver for");
return get(ui);
}

/**
* Returns the current instance. Will create one if needed and set its {@link #setQueryingOnUnload(boolean)}.
* @param queryingOnUnload Whether or not query at page close.
* Returns or creates an instance for a given UI.
* The result is associated with the UI, but not added to any of its components.
* @param ui A {@link UI} to register the instance of {@link UnloadObserver} in. Must not be {@code null}.
* @return An instance of {@link UnloadObserver}.
*/
public static UnloadObserver get(boolean queryingOnUnload) {
if(instance == null)
instance = new UnloadObserver(queryingOnUnload);
else instance.setQueryingOnUnload(queryingOnUnload);
public static UnloadObserver get(UI ui) {
UnloadObserver instance = ComponentUtil.getData(ui, UnloadObserver.class);
if(instance == null) {
instance = new UnloadObserver();
ComponentUtil.setData(ui, UnloadObserver.class, instance);
}
return instance;
}

Expand Down Expand Up @@ -131,9 +142,14 @@ protected void onDetach(DetachEvent detachEvent) {
super.onDetach(detachEvent);
}

@ClientCallable
private void unloadHappened() {
this.fireUnloadEvent(new UnloadEvent(this, false));
}

@ClientCallable
private void unloadAttempted() {
this.fireUnloadEvent(new UnloadEvent(this));
this.fireUnloadEvent(new UnloadEvent(this, true));
}

/**
Expand All @@ -152,5 +168,4 @@ protected void fireUnloadEvent(UnloadEvent event) {
public Registration addUnloadListener(UnloadListener listener) {
return this.getEventBus().addListener(UnloadEvent.class, listener);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,31 @@ export class UnloadObserver extends PolymerElement {
const src = this;
if (window.Vaadin.unloadObserver === undefined) {
window.Vaadin.unloadObserver = {
handler: undefined
attemptHandler: undefined
}
}
if (window.Vaadin.unloadObserver.handler !== undefined) {
window.removeEventListener('beforeunload', window.Vaadin.unloadObserver.handler);
if (window.Vaadin.unloadObserver.attemptHandler !== undefined) {
window.removeEventListener('beforeunload', window.Vaadin.unloadObserver.attemptHandler);
}
window.Vaadin.unloadObserver.handler = event => src.unloadHappened(src, event);
window.addEventListener('beforeunload', window.Vaadin.unloadObserver.handler);
window.Vaadin.unloadObserver.attemptHandler = event => src.unloadAttempted(src, event);
window.addEventListener('beforeunload', window.Vaadin.unloadObserver.attemptHandler);
}

/**
* Invoked in response to beforeunload browser event.
* @param source An unload observer.
* @param event Event that happened.
*/
unloadHappened(source, event) {
unloadAttempted(source, event) {
if (window.Vaadin.unloadObserver.query) {
console.log("UO: responding to unload attempt...");
event.preventDefault();
event.returnValue = '';
if (source.$server) {
source.$server.unloadAttempted();
}
}
else source.$server.unloadHappened();
}

/**
Expand Down

0 comments on commit 7c7d9eb

Please sign in to comment.