diff --git a/vaadin-touchkit-agpl/pom.xml b/vaadin-touchkit-agpl/pom.xml
index fa00a56f..12ac0c55 100644
--- a/vaadin-touchkit-agpl/pom.xml
+++ b/vaadin-touchkit-agpl/pom.xml
@@ -157,8 +157,8 @@
agpl
3.0
- [7.6.0.beta1,7.99.9999]
- 7.7.26
+ 7.7.28
+ 7.7.28
empty.properties
true
http://oss.sonatype.org/content/repositories/vaadin-snapshots/
diff --git a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/annotations/CacheManifestEnabled.java b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/annotations/CacheManifestEnabled.java
index 7662fd56..6b6a0d3e 100644
--- a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/annotations/CacheManifestEnabled.java
+++ b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/annotations/CacheManifestEnabled.java
@@ -22,10 +22,12 @@
import java.lang.annotation.Target;
/**
- * Disables o enable the manifest cache.
+ * This annotation is no longer needed as service worker and local storage is
+ * being used by Safari, Chrome and Firefox for now on.
*/
+@Deprecated
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CacheManifestEnabled {
- boolean value() default true;
+ boolean value() default true;
}
diff --git a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/gwt/client/offlinemode/CacheManifestStatusIndicator.java b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/gwt/client/offlinemode/CacheManifestStatusIndicator.java
index a08fcf80..e98f54c7 100644
--- a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/gwt/client/offlinemode/CacheManifestStatusIndicator.java
+++ b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/gwt/client/offlinemode/CacheManifestStatusIndicator.java
@@ -35,7 +35,8 @@ public class CacheManifestStatusIndicator implements EntryPoint {
// TODO(manolo): should be configurable via offline connector
private int updateCheckInterval = 1800000;
- private static final Logger logger = Logger.getLogger(CacheManifestStatusIndicator.class.getName());
+ private static final Logger logger = Logger
+ .getLogger(CacheManifestStatusIndicator.class.getName());
private static boolean confirmationRequired = true;
@@ -48,8 +49,8 @@ public void onModuleLoad() {
}
/**
- * Let the indicator ask the user to reload the application
- * when a new version of the app has been downloaded.
+ * Let the indicator ask the user to reload the application when a new
+ * version of the app has been downloaded.
*/
public static void setConfirmationRequired(boolean b) {
confirmationRequired = b;
@@ -59,7 +60,8 @@ public static void setConfirmationRequired(boolean b) {
* return true if we are downloading a new version of the app.
*/
public static boolean isUpdating() {
- return updating || getStatus() == CHECKING || getStatus() == DOWNLOADING;
+ return updating || getStatus() == CHECKING
+ || getStatus() == DOWNLOADING;
}
/**
@@ -67,7 +69,6 @@ public static boolean isUpdating() {
*/
public void init() {
loadSettingsFromLocalStorage();
- hookAllListeners(this);
scheduleUpdateChecker();
if (getStatus() == CHECKING || getStatus() == DOWNLOADING) {
showProgress();
@@ -79,8 +80,8 @@ public void init() {
private void pollForStatusOnAndroid() {
if (BrowserInfo.get().isAndroid()) {
- Scheduler.get().scheduleFixedPeriod(
- new Scheduler.RepeatingCommand() {
+ Scheduler.get()
+ .scheduleFixedPeriod(new Scheduler.RepeatingCommand() {
@Override
public boolean execute() {
if (updating) {
@@ -121,7 +122,8 @@ private void loadSettingsFromLocalStorage() {
&& !updateCheckIntervalStr.isEmpty()) {
// The value in local storage is in seconds, but we need
// milliseconds.
- updateCheckInterval = Integer.valueOf(updateCheckIntervalStr) * 1000;
+ updateCheckInterval = Integer.valueOf(updateCheckIntervalStr)
+ * 1000;
}
}
}
@@ -135,9 +137,8 @@ private void scheduleUpdateChecker() {
public boolean execute() {
// Don't try to update cache if already updating or app is
// paused
- if (!isUpdating()
- && OfflineModeEntrypoint.get().getNetworkStatus()
- .isAppRunning()) {
+ if (!isUpdating() && OfflineModeEntrypoint.get()
+ .getNetworkStatus().isAppRunning()) {
updateCache();
}
return true;
@@ -210,7 +211,8 @@ protected void hideProgress() {
* true to force reloading the site without asking the user.
*/
private void requestUpdate() {
- logger.info("Application cache updated, confirmationRequired=" + confirmationRequired);
+ logger.info("Application cache updated, confirmationRequired="
+ + confirmationRequired);
if (!confirmationRequired || Window.confirm(updateNowMessage)) {
Window.Location.reload();
}
@@ -219,48 +221,28 @@ private void requestUpdate() {
/**
* Hooks all listeners to the specified instance.
*
+ * @deprecated This is NOP as Safari, Chrome and Firefox do not need this
+ * anymore.
+ *
* @param instance
* the instance to hook the listeners to.
*/
+ @Deprecated
protected final native void hookAllListeners(
CacheManifestStatusIndicator instance)
/*-{
- $wnd.applicationCache.addEventListener('cached',
- function(event) {
- instance.@com.vaadin.addon.touchkit.gwt.client.offlinemode.CacheManifestStatusIndicator::onCacheEvent(Lcom/google/gwt/user/client/Event;)(event);
- }, false);
- $wnd.applicationCache.addEventListener('checking',
- function(event) {
- instance.@com.vaadin.addon.touchkit.gwt.client.offlinemode.CacheManifestStatusIndicator::onCacheEvent(Lcom/google/gwt/user/client/Event;)(event);
- }, false);
- $wnd.applicationCache.addEventListener('downloading',
- function(event) {
- instance.@com.vaadin.addon.touchkit.gwt.client.offlinemode.CacheManifestStatusIndicator::onCacheEvent(Lcom/google/gwt/user/client/Event;)(event);
- }, false);
- $wnd.applicationCache.addEventListener('noupdate',
- function(event) {
- instance.@com.vaadin.addon.touchkit.gwt.client.offlinemode.CacheManifestStatusIndicator::onCacheEvent(Lcom/google/gwt/user/client/Event;)(event);
- }, false);
- $wnd.applicationCache.addEventListener('updateready',
- function(event) {
- instance.@com.vaadin.addon.touchkit.gwt.client.offlinemode.CacheManifestStatusIndicator::onCacheEvent(Lcom/google/gwt/user/client/Event;)(event);
- }, false);
- $wnd.applicationCache.addEventListener('error',
- function(event) {
- instance.@com.vaadin.addon.touchkit.gwt.client.offlinemode.CacheManifestStatusIndicator::onError(Lcom/google/gwt/user/client/Event;)(event);
- }, false);
}-*/;
/**
* @return The status of the application cache. See the constants in this
- * class for possible values. Return 99 if application cache does
+ * class for possible values. Return 99 if application cache does
* not exist.
*/
private static native int getStatus()
/*-{
- if($wnd.applicationCache) {
+ if($wnd.applicationCache) {
return $wnd.applicationCache.status;
- }
+ }
return 99;
}-*/;
diff --git a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/ApplicationCacheSettings.java b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/ApplicationCacheSettings.java
index 132488c9..5951dddc 100644
--- a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/ApplicationCacheSettings.java
+++ b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/ApplicationCacheSettings.java
@@ -20,7 +20,7 @@
@SuppressWarnings("serial")
public class ApplicationCacheSettings implements BootstrapListener {
- private boolean cacheManifestEnabled = true;
+ private boolean cacheManifestEnabled = false;
private boolean offlineModeEnabled = true;
@Override
@@ -38,8 +38,7 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
final VaadinService service = response.getSession().getService();
final VaadinRequest request = response.getRequest();
- final String staticFilePath = service
- .getStaticFileLocation(request);
+ final String staticFilePath = service.getStaticFileLocation(request);
// VAADIN folder location
final String vaadinDir = staticFilePath + "/VAADIN/";
// Figure out widgetset
@@ -47,8 +46,7 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
response.getUiClass());
String widgetset = response.getUIProvider().getWidgetset(event);
if (widgetset == null) {
- widgetset = request.getService()
- .getConfiguredWidgetset(request);
+ widgetset = request.getService().getConfiguredWidgetset(request);
}
// Url for the widgetset
final String widgetsetUrl = String.format(
@@ -67,8 +65,7 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
if (isCacheManifestEnabled()) {
// Add cache manifest attribute to html tag
- document.getElementsByTag("html").attr(
- "manifest",
+ document.getElementsByTag("html").attr("manifest",
vaadinDir + "widgetsets/" + widgetset + "/"
+ generateManifestFileName(response));
}
@@ -113,21 +110,28 @@ protected String generateManifestFileName(BootstrapPageResponse response) {
}
/**
+ * @deprecated Safari, Chrome and Firefox use serviceworkerd and
+ * localstorage, so this is allways false with them.
+ *
* @return true if the cache manifest (and thus application cache) is
* enabled.
*/
+ @Deprecated
public boolean isCacheManifestEnabled() {
- return cacheManifestEnabled && !TouchKitSettings.supportsGooglePWA();
+ return false;
}
/**
* Enable or disable the cache manifest (and thus application cache).
*
+ * @deprecated Safari, Chrome and Firefox use serviceworkerd and
+ * localstorage, so this is allways false with them.
+ *
* @param cacheManifestEnabled
* true to enable.
*/
+ @Deprecated
public void setCacheManifestEnabled(boolean cacheManifestEnabled) {
- this.cacheManifestEnabled = cacheManifestEnabled;
}
/**
@@ -152,8 +156,8 @@ public void setOfflineModeEnabled(boolean offlineModeEnabled) {
* cache (== new version of the widget set).
*
* @param message
- * The new message. The default is
- * "There are updates ready to be installed. Would you like to restart now?"
+ * The new message. The default is "There are updates ready to be
+ * installed. Would you like to restart now?"
*/
public void setUpdateNowMessage(String message) {
LocalStorage.get().put(CacheManifestStatusIndicator.UPDATE_NOW_MSG_KEY,
diff --git a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/TouchKitSettings.java b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/TouchKitSettings.java
index 755312cf..6e4826e0 100644
--- a/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/TouchKitSettings.java
+++ b/vaadin-touchkit-agpl/src/main/java/com/vaadin/addon/touchkit/settings/TouchKitSettings.java
@@ -17,7 +17,6 @@
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
-import com.vaadin.addon.touchkit.annotations.CacheManifestEnabled;
import com.vaadin.addon.touchkit.annotations.OfflineModeEnabled;
import com.vaadin.addon.touchkit.server.TouchKitServlet;
import com.vaadin.addon.touchkit.service.ApplicationIcon;
@@ -47,8 +46,8 @@
* which is {@link TouchKitServlet} by default.
*/
@SuppressWarnings("serial")
-public class TouchKitSettings implements BootstrapListener,
- SessionInitListener, SystemMessagesProvider {
+public class TouchKitSettings implements BootstrapListener, SessionInitListener,
+ SystemMessagesProvider {
private List stronglyCachedResources;
@@ -182,28 +181,22 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
}
if (getApplicationCacheSettings() != null) {
OfflineModeEnabled offline = null;
- CacheManifestEnabled manifest = null;
Class> clazz = response.getUiClass();
if (clazz != null) {
offline = clazz.getAnnotation(OfflineModeEnabled.class);
- manifest = clazz.getAnnotation(CacheManifestEnabled.class);
}
- if (response.getSession().getService() instanceof VaadinServletService) {
+ if (response.getSession()
+ .getService() instanceof VaadinServletService) {
clazz = ((VaadinServletService) response.getSession()
.getService()).getServlet().getClass();
if (offline == null) {
offline = clazz.getAnnotation(OfflineModeEnabled.class);
}
- if (manifest == null) {
- manifest = clazz.getAnnotation(CacheManifestEnabled.class);
- }
}
- getApplicationCacheSettings().setCacheManifestEnabled(
- manifest == null || manifest.value());
- getApplicationCacheSettings().setOfflineModeEnabled(
- offline == null || offline.value());
+ getApplicationCacheSettings()
+ .setOfflineModeEnabled(offline == null || offline.value());
getApplicationCacheSettings().modifyBootstrapPage(response);
}
@@ -218,7 +211,8 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
element.attr("rel", "manifest");
element.attr("href", contextPath + "/manifest.json");
document.getElementsByTag("head").get(0).appendChild(element);
- // This meta tag is for some weird reason needed for 100% google PWA ;-)
+ // This meta tag is for some weird reason needed for 100% google PWA
+ // ;-)
element = document.createElement("meta");
element.attr("name", "theme-color");
element.attr("content", getWebAppSettings().getTheme_color());
@@ -228,27 +222,34 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
// TODO make this somehow more stable and cleaner
String text = document.body().toString().replaceAll("\n", "");
- Pattern p = Pattern.compile(".*widgetset\": \"([^\"]+)\"", Pattern.DOTALL);
+ Pattern p = Pattern.compile(".*widgetset\": \"([^\"]+)\"",
+ Pattern.DOTALL);
Matcher matcher = p.matcher(text);
boolean find = matcher.find();
String wsname = "";
if (find) {
- wsname = matcher.group(1);
+ wsname = matcher.group(1);
} else {
- return;
+ return;
}
-
- InputStream resourceAsStream = getClass().getResourceAsStream("/VAADIN/widgetsets/" + wsname + "/" + "safari.manifest");
+
+ InputStream resourceAsStream = getClass()
+ .getResourceAsStream("/VAADIN/widgetsets/" + wsname
+ + "/" + "safari.manifest");
// Might be null in case of for example fallback UI
if (resourceAsStream != null) {
List resources = new ArrayList();
try {
- final URI base = new URI(contextPath + "/VAADIN/widgetsets/" + wsname + "/");
- // the safari permutation is used by most mobile web apps
- // Read the cached files from the GWT generated manifest file for service workers as well
- List readLines = IOUtils.readLines(resourceAsStream);
+ final URI base = new URI(contextPath
+ + "/VAADIN/widgetsets/" + wsname + "/");
+ // the safari permutation is used by most mobile web
+ // apps
+ // Read the cached files from the GWT generated manifest
+ // file for service workers as well
+ List readLines = IOUtils
+ .readLines(resourceAsStream);
boolean cachedFilesStarted = false;
for (String readLine : readLines) {
if (readLine.startsWith("CACHE:")) {
@@ -263,43 +264,48 @@ public void modifyBootstrapPage(BootstrapPageResponse response) {
if (cachedFilesStarted) {
readLine = readLine.trim();
if (!readLine.isEmpty()) {
- readLine = readLine.replace("\\", "/");
+ readLine = readLine.replace("\\", "/");
URI resolved = base.resolve(readLine);
resources.add(resolved.toString());
}
}
}
} catch (IOException ex) {
- Logger.getLogger(TouchKitSettings.class.getName()).log(Level.SEVERE, null, ex);
+ Logger.getLogger(TouchKitSettings.class.getName())
+ .log(Level.SEVERE, null, ex);
} catch (URISyntaxException ex) {
- Logger.getLogger(TouchKitSettings.class.getName()).log(Level.SEVERE, null, ex);
+ Logger.getLogger(TouchKitSettings.class.getName())
+ .log(Level.SEVERE, null, ex);
}
this.stronglyCachedResources = resources;
}
}
- if (stronglyCachedResources != null && !stronglyCachedResources.isEmpty()) {
- Element serviceworkerregistration = document.createElement("script");
+ if (stronglyCachedResources != null
+ && !stronglyCachedResources.isEmpty()) {
+ Element serviceworkerregistration = document
+ .createElement("script");
serviceworkerregistration.attr("type", "text/javascript");
- serviceworkerregistration.appendText("if ('serviceWorker' in navigator) {\n"
- + " navigator.serviceWorker.register('"+contextPath+"/service-worker.js', { scope: '"+contextPath+"/' }).then(function(reg) {\n"
- + "\n"
- + " if(reg.installing) {\n"
- + " console.log('Service worker installing');\n"
- + " } else if(reg.waiting) {\n"
- + " console.log('Service worker installed');\n"
- + " } else if(reg.active) {\n"
- + " console.log('Service worker active');\n"
- + " }\n"
- + "\n"
- + " }).catch(function(error) {\n"
- + " console.log('Registration failed with ' + error);\n"
- + " });\n"
- + "}");
+ serviceworkerregistration
+ .appendText("if ('serviceWorker' in navigator) {\n"
+ + " navigator.serviceWorker.register('"
+ + contextPath
+ + "/service-worker.js', { scope: '"
+ + contextPath + "/' }).then(function(reg) {\n"
+ + "\n" + " if(reg.installing) {\n"
+ + " console.log('Service worker installing');\n"
+ + " } else if(reg.waiting) {\n"
+ + " console.log('Service worker installed');\n"
+ + " } else if(reg.active) {\n"
+ + " console.log('Service worker active');\n"
+ + " }\n" + "\n"
+ + " }).catch(function(error) {\n"
+ + " console.log('Registration failed with ' + error);\n"
+ + " });\n" + "}");
document.body().appendChild(serviceworkerregistration);
}
- }
+ }
}
@Override
@@ -307,26 +313,34 @@ public void sessionInit(SessionInitEvent event) throws ServiceException {
event.getSession().addBootstrapListener(this);
event.getSession().addRequestHandler(new RequestHandler() {
@Override
- public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException {
+ public boolean handleRequest(VaadinSession session,
+ VaadinRequest request, VaadinResponse response)
+ throws IOException {
final String pathInfo = request.getPathInfo();
String contextPath = request.getContextPath();
// Skip the request if the pathInfo is null
if (pathInfo == null) {
- return false;
+ return false;
}
if (pathInfo.endsWith("manifest.json")) {
// TODO write manifest.json using Jackson or similar
PrintWriter writer = response.getWriter();
- writer.append("{\n"
- + " \"short_name\": \"" + getWebAppSettings().getApplicationShortName() + "\",\n"
- + " \"name\": \"" + getWebAppSettings().getApplicationName() + "\",\n"
- + " \"display\": \"" + getWebAppSettings().getDisplay() + "\",\n"
- + " \"start_url\": \"" + contextPath + getWebAppSettings().getStart_url() + "\",\n"
- + " \"background_color\": \"" + getWebAppSettings().getBackground_color() + "\",\n"
- + " \"theme_color\": \"" + getWebAppSettings().getTheme_color() + "\",\n"
+ writer.append("{\n" + " \"short_name\": \""
+ + getWebAppSettings().getApplicationShortName()
+ + "\",\n" + " \"name\": \""
+ + getWebAppSettings().getApplicationName() + "\",\n"
+ + " \"display\": \""
+ + getWebAppSettings().getDisplay() + "\",\n"
+ + " \"start_url\": \"" + contextPath
+ + getWebAppSettings().getStart_url() + "\",\n"
+ + " \"background_color\": \""
+ + getWebAppSettings().getBackground_color()
+ + "\",\n" + " \"theme_color\": \""
+ + getWebAppSettings().getTheme_color() + "\",\n"
+ " \"icons\": [\n");
- final ApplicationIcon[] icons = getApplicationIcons().getApplicationIcons();
+ final ApplicationIcon[] icons = getApplicationIcons()
+ .getApplicationIcons();
for (int i = 0; i < icons.length; i++) {
ApplicationIcon icon = icons[i];
if (i > 0) {
@@ -350,7 +364,8 @@ public boolean handleRequest(VaadinSession session, VaadinRequest request, Vaadi
+ " caches.open(\"tkcache\").then(c => {\n"
+ " return c.addAll([\n");
- // TODO consider using https://github.com/GoogleChromeLabs/sw-precache
+ // TODO consider using
+ // https://github.com/GoogleChromeLabs/sw-precache
if (stronglyCachedResources != null) {
for (String stronglyCachedResource : stronglyCachedResources) {
writer.write("'");
@@ -358,32 +373,27 @@ public boolean handleRequest(VaadinSession session, VaadinRequest request, Vaadi
writer.write("',\n");
}
} else {
- Logger.getLogger(TouchKitSettings.class.getName()).log(Level.SEVERE, "strongly cached resources could not be found");
+ Logger.getLogger(TouchKitSettings.class.getName()).log(
+ Level.SEVERE,
+ "strongly cached resources could not be found");
}
writer.write(""
+ " ]).then(() => self.skipWaiting());\n"
- + " })\n"
- + " );\n"
- + "});\n"
- + "\n"
+ + " })\n" + " );\n" + "});\n" + "\n"
+ "self.addEventListener('fetch', e => {\n"
+ " e.respondWith(\n"
+ " caches.open(\"tkcache\").then(c => {\n"
+ " return c.match(e.request).then(res => {\n"
+ " return res || fetch(e.request)\n"
- + " });\n"
- + " })\n"
- + " );\n"
- + "});");
+ + " });\n" + " })\n" + " );\n" + "});");
return true;
}
return false;
}
- }
- );
+ });
}
/**
@@ -457,15 +467,20 @@ public SystemMessages getSystemMessages(
}
/**
- * @return true if Google style service worker + json manifest style PWA
- * should be used instead of original iOS style home screen web app thingies.
+ * @return true if Google style service worker + json manifest style PWA
+ * should be used instead of original iOS style home screen web app
+ * thingies.
*/
public static boolean supportsGooglePWA() {
try {
- VaadinRequest currentRequest = VaadinServletService.getCurrentRequest();
- String useragentheader = currentRequest.getHeader("User-Agent").toLowerCase();
+ VaadinRequest currentRequest = VaadinServletService
+ .getCurrentRequest();
+ String useragentheader = currentRequest.getHeader("User-Agent")
+ .toLowerCase();
// Simply expect all chromes to support
- if (useragentheader.contains("chrome") || useragentheader.contains("firefox")) {
+ if (useragentheader.contains("chrome")
+ || useragentheader.contains("firefox")
+ || useragentheader.contains("safari")) {
return true;
}
} catch (Exception e) {