Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add abstract layer for displaying elements #3

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,47 @@
[![Build Status](https://travis-ci.org/gwtplus/gwt-activity.svg?branch=master)](https://travis-ci.org/gwtplus/gwt-activity)
[![jitpack.io](https://jitpack.io/v/gwtplus/gwt-activity.svg)](https://jitpack.io/#gwtplus/gwt-activity)

Preparing for GWT 3 and j2cl
A future-proof port of the `com.google.gwt.activity.Activity` GWT module, with no dependency on `gwt-user` (besides the Java Runtime Emulation), to prepare for GWT 3 / J2Cl.

## Migrating from `com.google.gwt.activity.Activity`

1. Add the dependency to your build.

For Maven:

```xml
<dependency>
<groupId>org.gwtproject.activity</groupId>
<artifactId>gwt-activity</artifactId>
<version>HEAD-SNAPSHOT</version>
</dependency>
```

For Gradle:

```gradle
implementation("org.gwtproject.activity:gwt-activity:HEAD-SNAPSHOT")
```

1. Update your GWT module to use

```xml
<inherits name="org.gwtproject.activity.Activity" />
```

1. Change the `import`s in your Java source files:

```java
import org.gwtproject.activity.*;
```

1. Provide implementation of `ActivityDisplay<V>` or use any of provided ones (`WidgetActivityDisplay` from `WidgetActivity` module or `ElementalActivityDisplay` from `ElementalActivity`. Note that `ActivityDisplay` uses `show()` instead od `setWidget()`.

1. Specialize other `org.gwtproject.activity.*` references to `<V>`


## Dependencies

GWT Activity depends on the following modules:
* gwt-places
* gwt-event
17 changes: 16 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>

<java.release>1.8</java.release>
<gwt.version>2.8.2</gwt.version>
<gwt.version>2.9.0</gwt.version>
</properties>

<dependencies>
Expand All @@ -66,6 +66,20 @@
<version>HEAD-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.google.elemental2</groupId>
<artifactId>elemental2-dom</artifactId>
<version>1.1.0</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.gwtproject.widgets</groupId>
<artifactId>gwt-widgets</artifactId>
<version>1.0-SNAPSHOT</version>
<optional>true</optional>
</dependency>

<!-- Testing -->
<dependency>
<groupId>junit</groupId>
Expand Down Expand Up @@ -177,6 +191,7 @@
<configuration>
<includes>
<include>org/gwtproject/activity/ActivityJreSuite.java</include>
<include>org/gwtproject/activity/widget/WidgetActivityJreSuite.java</include>
</includes>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/

/**
* Temporary port until proper dependency is not available as snapshot
*
* FIXME: remove whole package
* Classes used to implement app navigation using elemental.
*/
package org.gwtproject.user;
package org.gwtproject.activity.elemental;
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2010 Google Inc.
*
* 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 org.gwtproject.activity.elemental.shared;

import org.gwtproject.activity.shared.ActivityDisplay;

import elemental2.dom.HTMLElement;

/**
* {@link ActivityDisplay} which wraps {@link HTMLElement} to provide
* display for {@link HTMLElement} views.
*/
public class ElementalActivityDisplay implements ActivityDisplay<HTMLElement> {

public ElementalActivityDisplay(HTMLElement delegate) {
this.delegate = delegate;
}

public void show(HTMLElement view) {

if (this.view == view) {
return;
}

while (delegate.firstChild != null) {
delegate.removeChild(delegate.firstChild);
}

if (view != null) {
delegate.appendChild(view);
}

this.view = view;
}

private final HTMLElement delegate;

private HTMLElement view;

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
/**
* Simple Activity implementation that is always willing to stop, and does
* nothing onStop and onCancel.
*
* @param <V> view type ({@code IsWidget}, {@code HTMLElement}, ...)
*/
public abstract class AbstractActivity implements Activity {
public abstract class AbstractActivity<V> implements Activity<V> {

public String mayStop() {
return null;
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/org/gwtproject/activity/shared/Activity.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
package org.gwtproject.activity.shared;

import org.gwtproject.event.shared.EventBus;
import org.gwtproject.user.client.ui.AcceptsOneWidget;

/**
* Implemented by objects that control a piece of user interface, with a life
* cycle managed by an {@link ActivityManager}, in response to
* {@link org.gwtproject.place.shared.PlaceChangeEvent} events as the user
* navigates through the app.
*
* @param <V> view type ({@code IsWidget}, {@code HTMLElement}, ...)
*/
public interface Activity {
public interface Activity<V> {

/**
* Called when the user is trying to navigate away from this activity.
Expand All @@ -50,7 +51,7 @@ public interface Activity {
* Called when the Activity should ready its widget for the user. When the
* widget is ready (typically after an RPC response has been received),
* receiver should present it by calling
* {@link AcceptsOneWidget#setWidget} on the given panel.
* {@link ActivityDisplay#show} on the given panel.
* <p>
* Any handlers attached to the provided event bus will be de-registered when
* the activity is stopped, so activities will rarely need to hold on to the
Expand All @@ -60,5 +61,5 @@ public interface Activity {
* @param panel the panel to display this activity's widget when it is ready
* @param eventBus the event bus
*/
void start(AcceptsOneWidget panel, EventBus eventBus);
void start(ActivityDisplay<V> panel, EventBus eventBus);
}
36 changes: 36 additions & 0 deletions src/main/java/org/gwtproject/activity/shared/ActivityDisplay.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2010 Google Inc.
*
* 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 org.gwtproject.activity.shared;

import org.gwtproject.activity.widget.shared.WidgetActivityDisplay;

/** Display used to show views of type {@code V}.
*
* @param <V> view type ({@code IsWidget}, {@code HTMLElement}, ...)
*/
public interface ActivityDisplay<V> {

/**
* Set the element to display, replacing the previously displayed
* element if there was one.
*
* @param view object to display, or <code>null</code> to clear display
*
* @see WidgetActivityDisplay
*/
void show(V view);

}
45 changes: 23 additions & 22 deletions src/main/java/org/gwtproject/activity/shared/ActivityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import org.gwtproject.event.shared.UmbrellaException;
import org.gwtproject.place.shared.PlaceChangeEvent;
import org.gwtproject.place.shared.PlaceChangeRequestEvent;
import org.gwtproject.user.client.ui.AcceptsOneWidget;
import org.gwtproject.user.client.ui.IsWidget;

import java.util.LinkedHashSet;
import java.util.Set;
Expand All @@ -31,34 +29,37 @@
* Manages {@link Activity} objects that should be kicked off in response to
* {@link PlaceChangeEvent} events. Each activity can start itself
* asynchronously, and provides a widget to be shown when it's ready to run.
*
* @param <V> view type ({@code IsWidget}, {@code HTMLElement}, ...)
*/
public class ActivityManager implements PlaceChangeEvent.Handler, PlaceChangeRequestEvent.Handler {
public class ActivityManager<V> implements PlaceChangeEvent.Handler,
PlaceChangeRequestEvent.Handler {

/**
* Wraps our real display to prevent an Activity from taking it over if it is
* not the currentActivity.
*/
private class ProtectedDisplay implements AcceptsOneWidget {
private final Activity activity;
private class ProtectedDisplay implements ActivityDisplay<V> {
private final Activity<V> activity;

ProtectedDisplay(Activity activity) {
ProtectedDisplay(Activity<V> activity) {
this.activity = activity;
}

public void setWidget(IsWidget view) {
public void show(V view) {
if (this.activity == ActivityManager.this.currentActivity) {
startingNext = false;
showWidget(view);
}
}
}

private static final Activity NULL_ACTIVITY = new AbstractActivity() {
public void start(AcceptsOneWidget panel, EventBus eventBus) {
private final Activity<V> nullActivity = new AbstractActivity<V>() {
public void start(ActivityDisplay<V> panel, EventBus eventBus) {
}
};

private final ActivityMapper mapper;
private final ActivityMapper<V> mapper;

private final EventBus eventBus;

Expand All @@ -68,9 +69,9 @@ public void start(AcceptsOneWidget panel, EventBus eventBus) {
*/
private final ResettableEventBus stopperedEventBus;

private Activity currentActivity = NULL_ACTIVITY;
private Activity<V> currentActivity = nullActivity;

private AcceptsOneWidget display;
private ActivityDisplay<V> display;

private boolean startingNext = false;

Expand All @@ -84,7 +85,7 @@ public void start(AcceptsOneWidget panel, EventBus eventBus) {
* @param eventBus source of {@link PlaceChangeEvent} and
* {@link PlaceChangeRequestEvent} events.
*/
public ActivityManager(ActivityMapper mapper, EventBus eventBus) {
public ActivityManager(ActivityMapper<V> mapper, EventBus eventBus) {
this.mapper = mapper;
this.eventBus = eventBus;
this.stopperedEventBus = new ResettableEventBus(eventBus);
Expand Down Expand Up @@ -113,14 +114,14 @@ public EventBus getActiveEventBus() {
* treatment.
*/
public void onPlaceChange(PlaceChangeEvent event) {
Activity nextActivity = getNextActivity(event);
Activity<V> nextActivity = getNextActivity(event);

Throwable caughtOnStop = null;
Throwable caughtOnCancel = null;
Throwable caughtOnStart = null;

if (nextActivity == null) {
nextActivity = NULL_ACTIVITY;
nextActivity = nullActivity;
}

if (currentActivity.equals(nextActivity)) {
Expand All @@ -131,9 +132,9 @@ public void onPlaceChange(PlaceChangeEvent event) {
// The place changed again before the new current activity showed its
// widget
caughtOnCancel = tryStopOrCancel(false);
currentActivity = NULL_ACTIVITY;
currentActivity = nullActivity;
startingNext = false;
} else if (!currentActivity.equals(NULL_ACTIVITY)) {
} else if (!currentActivity.equals(nullActivity)) {
showWidget(null);

/*
Expand All @@ -146,7 +147,7 @@ public void onPlaceChange(PlaceChangeEvent event) {

currentActivity = nextActivity;

if (currentActivity.equals(NULL_ACTIVITY)) {
if (currentActivity.equals(nullActivity)) {
showWidget(null);
} else {
startingNext = true;
Expand Down Expand Up @@ -189,7 +190,7 @@ public void onPlaceChangeRequest(PlaceChangeRequestEvent event) {
*
* @param display an instance of AcceptsOneWidget
*/
public void setDisplay(AcceptsOneWidget display) {
public void setDisplay(ActivityDisplay<V> display) {
boolean wasActive = (null != this.display);
boolean willBeActive = (null != display);
this.display = display;
Expand All @@ -198,7 +199,7 @@ public void setDisplay(AcceptsOneWidget display) {
}
}

private Activity getNextActivity(PlaceChangeEvent event) {
private Activity<V> getNextActivity(PlaceChangeEvent event) {
if (display == null) {
/*
* Display may have been nulled during PlaceChangeEvent dispatch. Don't
Expand All @@ -210,9 +211,9 @@ private Activity getNextActivity(PlaceChangeEvent event) {
return mapper.getActivity(event.getNewPlace());
}

private void showWidget(IsWidget view) {
private void showWidget(V view) {
if (display != null) {
display.setWidget(view);
display.show(view);
}
}

Expand Down
Loading