Skip to content

Commit

Permalink
fix: Add missing media-queries and resources for PWA splash screen (#…
Browse files Browse the repository at this point in the history
…13923) (#13950)

Manual CherryPick from #13923
  • Loading branch information
taefi authored Jun 13, 2022
1 parent 3391348 commit 524eff5
Show file tree
Hide file tree
Showing 6 changed files with 382 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,15 @@ private void setupPwa(Document document, BootstrapContext context) {
head.appendElement(META_TAG)
.attr("name", "apple-mobile-web-app-capable")
.attr(CONTENT_ATTRIBUTE, "yes");
head.appendElement(META_TAG)
.attr("name", "mobile-web-app-capable")
.attr(CONTENT_ATTRIBUTE, "yes");
head.appendElement(META_TAG)
.attr("name", "apple-touch-fullscreen")
.attr(CONTENT_ATTRIBUTE, "yes");
head.appendElement(META_TAG)
.attr("name", "apple-mobile-web-app-title")
.attr(CONTENT_ATTRIBUTE, config.getShortName());

// Theme color
head.appendElement(META_TAG).attr("name", "theme-color")
Expand Down
9 changes: 9 additions & 0 deletions flow-server/src/main/java/com/vaadin/flow/server/PwaIcon.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ public String getType() {
return attributes.get("type");
}

/**
* Gets the value of the {@literal rel} attribute.
*
* @return value of the {@literal rel} attribute
*/
String getRel() {
return attributes.get("rel");
}

/**
* Gets the icon {@link Domain}.
*
Expand Down
137 changes: 119 additions & 18 deletions flow-server/src/main/java/com/vaadin/flow/server/PwaRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ public class PwaRegistry implements Serializable {
private static final String META_INF_RESOURCES = "/META-INF/resources";
private static final String HEADLESS_PROPERTY = "java.awt.headless";
private static final String APPLE_STARTUP_IMAGE = "apple-touch-startup-image";
private static final String APPLE_IMAGE_MEDIA = "(device-width: %dpx) and (device-height: %dpx) "
+ "and (-webkit-device-pixel-ratio: %d)";
private static final String APPLE_IMAGE_MEDIA = "screen and (device-width: %dpx) and (device-height: %dpx)"
+ " and (-webkit-device-pixel-ratio: %d) and (orientation: %s)";
private static final String ORIENTATION_PORTRAIT = "portrait";
private static final String ORIENTATION_LANDSCAPE = "landscape";
public static final String WORKBOX_FOLDER = "VAADIN/static/server/workbox/";
private static final String WORKBOX_CACHE_FORMAT = "{ url: '%s', revision: '%s' }";

Expand Down Expand Up @@ -494,25 +496,124 @@ private static List<PwaIcon> getIconTemplates(String baseName) {
"apple-touch-icon", ""));

// IOS device specific splash screens
// iPhone X (1125px x 2436px)
// iPad Pro 12.9 Portrait:
icons.add(new PwaIcon(2048, 2732, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
1024, 1366, 2, ORIENTATION_PORTRAIT)));
// iPad Pro 12.9 Landscape:
icons.add(new PwaIcon(2732, 2048, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
1024, 1366, 2, ORIENTATION_LANDSCAPE)));

// iPad Pro 11, 10.5 Portrait:
icons.add(new PwaIcon(1668, 2388, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
834, 1194, 2, ORIENTATION_PORTRAIT)));
// iPad Pro 11, 10.5 Landscape:
icons.add(new PwaIcon(2388, 1668, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
834, 1194, 2, ORIENTATION_LANDSCAPE)));

// iPad Air 10.5 Portrait:
icons.add(new PwaIcon(1668, 2224, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
834, 1112, 2, ORIENTATION_PORTRAIT)));
// iPad Air 10.5 Landscape:
icons.add(new PwaIcon(2224, 1668, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
834, 1112, 2, ORIENTATION_LANDSCAPE)));

// iPad 10.2 Portrait:
icons.add(new PwaIcon(1620, 2160, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
768, 1024, 2, ORIENTATION_PORTRAIT)));
// iPad 10.2 Landscape:
icons.add(new PwaIcon(2160, 1620, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
768, 1024, 2, ORIENTATION_LANDSCAPE)));

// iPad Pro 9.7, iPad Air 9.7, iPad 9.7, iPad mini 7.9 portrait
icons.add(new PwaIcon(1536, 2048, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
768, 1024, 2, ORIENTATION_PORTRAIT)));
// iPad Pro 9.7, iPad Air 9.7, iPad 9.7, iPad mini 7.9 landscape
icons.add(new PwaIcon(2048, 1536, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
768, 1024, 2, ORIENTATION_LANDSCAPE)));

// iPhone 13 Pro Max, iPhone 12 Pro Max portrait
icons.add(new PwaIcon(1284, 2778, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
428, 926, 3, ORIENTATION_PORTRAIT)));
// iPhone 13 Pro Max, iPhone 12 Pro Max landscape
icons.add(new PwaIcon(2778, 1284, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
428, 926, 3, ORIENTATION_LANDSCAPE)));

// iPhone 13 Pro, iPhone 13, iPhone 12 Pro, iPhone 12 portrait
icons.add(new PwaIcon(1170, 2532, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
390, 844, 3, ORIENTATION_PORTRAIT)));
// iPhone 13 Pro, iPhone 13, iPhone 12 Pro, iPhone 12 landscape
icons.add(new PwaIcon(2532, 1170, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
390, 844, 3, ORIENTATION_LANDSCAPE)));

// iPhone 13 Mini, iPhone 12 Mini, iPhone 11 Pro, iPhone XS, iPhone X
// portrait
icons.add(new PwaIcon(1125, 2436, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE,
String.format(APPLE_IMAGE_MEDIA, 375, 812, 3)));

// iPhone 8, 7, 6s, 6 (750px x 1334px)
icons.add(new PwaIcon(750, 1334, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE,
String.format(APPLE_IMAGE_MEDIA, 375, 667, 2)));

// iPhone 8 Plus, 7 Plus, 6s Plus, 6 Plus (1242px x 2208px)
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
375, 812, 3, ORIENTATION_PORTRAIT)));
// iPhone 13 Mini, iPhone 12 Mini, iPhone 11 Pro, iPhone XS, iPhone X
// landscape
icons.add(new PwaIcon(2436, 1125, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
375, 812, 3, ORIENTATION_LANDSCAPE)));

// iPhone 11 Pro Max, iPhone XS Max portrait
icons.add(new PwaIcon(1242, 2688, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
414, 896, 3, ORIENTATION_PORTRAIT)));
// iPhone 11 Pro Max, iPhone XS Max landscape
icons.add(new PwaIcon(2688, 1242, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
414, 896, 3, ORIENTATION_LANDSCAPE)));

// iPhone 11, iPhone XR portrait
icons.add(new PwaIcon(828, 1792, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA, 414, 896,
2, ORIENTATION_PORTRAIT)));
// iPhone 11, iPhone XR landscape
icons.add(new PwaIcon(1792, 828, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA, 414, 896,
2, ORIENTATION_LANDSCAPE)));

// iPhone 8 Plus, 7 Plus, 6s Plus, 6 Plus portrait
icons.add(new PwaIcon(1242, 2208, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE,
String.format(APPLE_IMAGE_MEDIA, 414, 763, 3)));

// iPhone 5 (640px x 1136px)
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
414, 736, 3, ORIENTATION_PORTRAIT)));
// iPhone 8 Plus, 7 Plus, 6s Plus, 6 Plus landscape
icons.add(new PwaIcon(2208, 1242, baseName, PwaIcon.Domain.HEADER,
false, APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA,
414, 736, 3, ORIENTATION_LANDSCAPE)));

// iPhone 8, 7, 6s, 6, SE 4.7 portrait
icons.add(new PwaIcon(750, 1334, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA, 375, 667,
2, ORIENTATION_PORTRAIT)));
// iPhone 8, 7, 6s, 6, SE 4.7 landscape
icons.add(new PwaIcon(1334, 750, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA, 375, 667,
2, ORIENTATION_LANDSCAPE)));

// iPhone 5, SE 4, iPod touch 5th Gen and later portrait
icons.add(new PwaIcon(640, 1136, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE,
String.format(APPLE_IMAGE_MEDIA, 320, 568, 2)));
APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA, 320, 568,
2, ORIENTATION_PORTRAIT)));
// iPhone 5, SE 4, iPod touch 5th Gen and later landscape
icons.add(new PwaIcon(1136, 640, baseName, PwaIcon.Domain.HEADER, false,
APPLE_STARTUP_IMAGE, String.format(APPLE_IMAGE_MEDIA, 320, 568,
2, ORIENTATION_LANDSCAPE)));

return icons;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,28 +684,27 @@ public void page_configurator_append_inline_form_files()
Document page = pageBuilder.getBootstrapPage(new BootstrapContext(
request, null, session, testUI, this::contextRootRelativePath));

Elements allElements = page.head().getAllElements();
// Note element 0 is the full head element.
assertStringEquals(
String scripts = page.getElementsByTag("script").toString();

Assert.assertTrue(
"File javascript should have been appended to head element",
"<script type=\"text/javascript\">window.messages = window.messages || [];\n"
+ "window.messages.push(\"inline.js\");</script>",
allElements.get(allElements.size() - 3).toString());
assertStringEquals(
"File html should have been appended to head element",
"<script type=\"text/javascript\">\n"
scripts.contains(
"<script type=\"text/javascript\">window.messages = window.messages || [];\n"
+ "window.messages.push(\"inline.js\");</script>"));
Assert.assertTrue("File html should have been appended to head element",
scripts.contains("<script type=\"text/javascript\">\n"
+ " // document.body might not yet be accessible, so just leave a message\n"
+ " window.messages = window.messages || [];\n"
+ " window.messages.push(\"inline.html\");\n"
+ "</script>",
allElements.get(allElements.size() - 2).toString());
assertStringEquals("File css should have been appended to head element",
"<style type=\"text/css\">/* inline.css */\n" + "\n"
+ "#preloadedDiv {\n"
+ "</script>"));

String styles = page.getElementsByTag("style").toString();
Assert.assertTrue("File css should have been appended to head element",
styles.contains("<style type=\"text/css\">/* inline.css */\n"
+ "\n" + "#preloadedDiv {\n"
+ " color: rgba(255, 255, 0, 1);\n" + "}\n" + "\n"
+ "#inlineCssTestDiv {\n"
+ " color: rgba(255, 255, 0, 1);\n" + "}</style>",
allElements.get(allElements.size() - 1).toString());
+ " color: rgba(255, 255, 0, 1);\n" + "}</style>"));
}

@Test // 3036
Expand Down Expand Up @@ -1035,13 +1034,10 @@ public void force_wrapping_of_file()
Document page = pageBuilder.getBootstrapPage(new BootstrapContext(
request, null, session, testUI, this::contextRootRelativePath));

Elements allElements = page.head().getAllElements();

assertStringEquals(
"File css should have been prepended to body element",
"<style type=\"text/css\">window.messages = window.messages || [];\n"
+ "window.messages.push(\"inline.js\");</style>",
allElements.get(allElements.size() - 1).toString());
assertTrue("File css should have been prepended to body element",
page.getElementsByTag("style").toString().contains(
"<style type=\"text/css\">window.messages = window.messages || [];\n"
+ "window.messages.push(\"inline.js\");</style>"));
}

@Test // 3197
Expand Down
Loading

0 comments on commit 524eff5

Please sign in to comment.