Code Monkey home page Code Monkey logo

pwacompat's Introduction

Build Status

PWACompat is a library that brings the Web App Manifest to non-compliant browsers for better Progressive Web Apps. This mostly means creating splash screens and icons for Mobile Safari, as well as supporting IE/Edge's Pinned Sites feature.

So, if you've created a manifest.webmanifest but want to have wide support everywhere else—through legacy HTML tags for icons and theming—look no further. We recommend including it from a CDN to get the latest version, or bundling it yourself:

<link rel="manifest" href="manifest.webmanifest" />
<script async src="https://cdn.jsdelivr.net/npm/pwacompat" crossorigin="anonymous"></script>
<!-- or another CDN -->
<script async src="https://unpkg.com/pwacompat" crossorigin="anonymous"></script>

And you're done^! 🎉📄

For more on the Web App Manifest, read 📖 how to add a Web App Manifest and mobile-proof your site, watch 📹 theming as part of The Standard, or check out 📬 the Web Fundamentals post on PWACompat.

PWACompat explainer
PWACompat takes your regular manifest and enhances other browsers

^Best Practice & Caveats

While PWACompat can generate most icons, meta tags etc that your PWA might need, it's best practice to include at least one <link rel="icon" ... />. This is standardized and older browsers, along with search engines, may use it from your page to display an icon. For example:

<link rel="manifest" href="manifest.webmanifest" />
<script async src="path/to/pwacompat.min.js"></script>
<!-- include icon also from manifest -->
<link rel="icon" type="image/png" href="res/icon-128.png" sizes="128x128" />

You should also consider only loading PWACompat after your site is loaded, as adding your site to a homescreen is a pretty rare operation. This is the approach taken on v8.dev and Emojityper.

iOS

PWACompat looks for a viewport tag which includes viewport-fit=cover, such as <meta name="viewport" content="viewport-fit=cover">. If this tag is detected, PWACompat will generate a meta tag that makes your PWA load in fullscreen mode—this is particularly useful for devices with a notch.

You can customize the generated splash screen's font by using a CSS Variable. For example:

<style>
  link[rel="manifest"] {
     --pwacompat-splash-font: 24px Verdana;
  }
</style>

This is set directly as a canvas font, so you must as a minimum include size and family. The default value is "24px HelveticaNeue-CondensedBold".

⚠️ PWACompat won't wait for your fonts to load, so if you're using custom fonts, be sure to only load the library after they're ready.

Old Versions

Prior to iOS 12.2, Mobile Safari opens external sites in the regular browser, meaning that flows like Oauth won't complete correctly. This isn't a problem with PWACompat, but is an issue with PWAs on iOS generally.

Session Storage

PWACompat uses window.sessionStorage to cache your site's manifest (and on iOS, any updated icons and generated splash screens). This expires after a user navigates away from your page or closes their tab.

Details

What does PWACompat actually do? If you provide a Web App Manifest, PWACompat will update your page and:

  • Create meta icon tags for all icons in the manifest (e.g., for a favicon, older browsers)
  • Create fallback meta tags for various browsers (e.g., iOS, WebKit/Chromium forks etc) describing how a PWA should open
  • Sets the theme color based on the manifest

For Safari, PWACompat also:

  • Sets apple-mobile-web-app-capable (opening without a browser chrome) for display modes standalone, fullscreen or minimal-ui
  • Creates apple-touch-icon images, adding the manifest background to transparent icons: otherwise, iOS renders transparency as black
  • Creates dynamic splash images, closely matching the splash images generated for Chromium-based browsers

For IE and Edge:

For PWAs on Windows with access to UWP APIs:

  • Sets the titlebar color

Do you think PWACompat should support backfilling more HTML tags needed for older browsers? Let us know!

Demo

For a demo, try adding Emojityper or the demo site to an iOS home screen (to see splash screens and icons). You can also install Emojityper from the Microsoft Store (where the titlebar color is automatically set the manifest's theme_color).

Support

This is supported in most modern browsers (UC Browser, Safari, Firefox, Chrome, IE10+), and fails silenty when unsupported. Mobile Safari benefits the most from PWACompat, as generating a large number of splash screens manually is a complex task.

Web App Manifest

Your Web App Manifest is:

  • normally named manifest.webmanifest (although some folks name it manifest.json)
  • referenced from all pages on your site like <link rel="manifest" href="path/to/manifest.webmanifest" />
  • and should look a bit like this:
{
  "name": "Always Be Progressive",
  "short_name": "Progressive!",
  "display": "browser",
  "start_url": "/",
  "background_color": "#102a48",
  "icons": [
    {
      "src": "res/icon-256.png",
      "sizes": "256x256"
    },
    {
      "src": "res/icon-128.png",
      "sizes": "128x128"
    }
  ]
}

For more information on the Web App Manifest, and how e.g., modern browsers will prompt engaged users to install your site to their home screen, check out Web Fundamentals. There's also a number of online generators.

Release

Compile code with Closure Compiler.

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name pwacompat.min.js
// ==/ClosureCompiler==

// code here

pwacompat's People

Contributors

dependabot[bot] avatar frusznyak avatar gangsthub avatar jpmedley avatar lordfido avatar notwoods avatar samthor avatar tomayac avatar ykyk1218 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pwacompat's Issues

Add “from (someone)” as WhatsApp?

Is there a way to add “from (someone)” as WhatsApp with pwacompat? I’d like to make this effect, but I don’t know if it’s possible and how to do it.
Here is an example:
image1

P.S.: I need this with iOS, so, I don’t care about modify anything on manifest icons (for chrome) but, for example, only add a new key-value pair on my manifest (that pwacompat adds to my iOS icons).

Remove the manifest from iOS to allow OAuth redirect to works

Lot of people are having issue with redirect at OAuth flow when using the apple-mobile-web-app-capable feature of iOS:

I believe it can be solved by changing the:
<link rel="manifest" href="manifest.json">
to
<link rel="no-on-ios" href="manifest.json">
when on iOS.

It prevent the iOS Safari to process the manifest (which cause the bug)

So, i believe that this pice of code could be inside pwacompat.js to allow many of PWAs use OAuth login:

   var iOS = !!navigator.platform && /iPhone/.test(navigator.platform);
   if(iOS) {
      document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
   }

At least until apple fix this issue (don't know where or if is been tracked).

https://forums.developer.apple.com/thread/100524

Prioritize maskable icons for apple-touch-icon

If an icon has "purpose": "maskable", that indicates it should not be transparent and is suited to be masked to shapes like iOS' rounded squares.

Some potential behaviour options:

  • Include the maskable icons with no priority (current behaviour)
  • If a maskable icon is present, discard the non-maskable icons and only use maskable icons for apple-touch-icon
  • Rank maskable icons higher somehow (does Safari use the first icon it encounters?)

meta description

It would be nice to read description from the manifest and add it as <meta name="description" /> if that tag is not already present.

Update Windows ApplicationViewTitleBar with theme-color over time

If a page changes its internal, local theme-color meta tag, should we update the ApplicationViewTitleBar with it?

Or should it just be set to the initial theme from the manifest?

Chrome, for instance, uses the manifest's theme color only for initial load, then deferring to the page.

Wrong system bar color on iOS when using safari

I'm using "theme_color": "#191919", wich I consider a dark color. This bug can be reproduced when using #000000 also.

Then, I'm adding my PWA to my homescreen and the iOS system bar is being painted on white, instead of black.

If I change the theme_color value on my manifest to #FFFFFF, then the iOS system bar is painted on black. The opposite of my theme_color.

I've being looking into the code, and the problem is on pwacompat.js:276, where I think a change should be made:

-    meta('apple-mobile-web-app-status-bar-style', themeIsLight ? 'default' : 'black');
+    meta('apple-mobile-web-app-status-bar-style', themeIsLight ? 'black' : 'default');

This would be also coherent with the same feature for MS Edge (on pwacompat.js:284)

CSS modification

I get RTL css from Framework 7 website and It worked well in shinyMobile dashboard, however, when I modified css (for example: .md .tabbar .tab-link, .md .tabbar-labels .tab-link ) file to change header and tab bar menu color, it did not work in iOS and iPadOS. It works well on android, windows, and MacOS.

caveats?

I'm wondering if there should be a list of short-comings that this library can't handle. For example, "start_url" won't be used in iOS and it just uses the current URL. Also, all regular web links in iOS are opened in a new Safari window and the "scope" value is ignored. (apparently some of these things are fixed in newer version of iOS that support a web manifest, but I'm curious how that handles both a manifest and the meta attributes being set... unfortunately I have no way of testing it)

Splash screen not shown when added on iPad with landscape orientation

When I add my PWA to home screen on iPad 6 (2048x1536), the splash screen is only shown when I add it in portrait mode. (I can close it and then open it horizontally with the splash screen being shown without any problem).

However, when I add the PWA to home screen when the iPad is in landscape mode and open the PWA, the splash screen is not shown (Only a white screen).

I tried to add orientation:"landscape"/"portrait"/"any" to manifest.json and also played with meta tags without any success.
Bug can be reproduced with demo PWA emojityper.com and is also present on the newest version 2.0.14.

Unexpected token in position 447

Chrome devtools prints out a warning from pwacompat version 2.0.8:

pwacompat.min.js:1 pwacompat.js error SyntaxError: Unexpected token / in JSON at position 447
    at JSON.parse (<anonymous>)
    at XMLHttpRequest.e.onload (pwacompat.min.js:1)

Initial Height on iOS w/ Notch + viewport-fit=cover

The initial view (not the splash screen) height appears short when viewport-fit=cover is on the viewport meta tag. There doesn't appear to be a way to resolve this using only CSS (or the iOS provided env(safe-area-inset-top) spacing values).

Not sure if this a PWA specific issue, or rather an iOS "notch CSS" issue.

I can get the height of the gap using env(safe-area-inset-top) but cannot get it to go below the bottom of the body, even using a negative value like so: bottom: calc(-1 * env(safe_area-inset-top)). This is strange, because I can manipulate the top page elements (header, etc.) just fine with CSS using those values... Any who, figured I would post just in case.

External manifest

When having manifest.json at a different location (CDN) as the web page, and having relative paths to the icons in the manifest, the polyfill will not work. It would be nice if the polyfill takes the domain of the manifest.json into account and add that to the image source paths.

Maskable Icons

Currently, PWACompat appears to ignore the "purpose": "maskable" attribute on an icon, and use it as if it was a normal icon. Please filter maskable icons out, or add proper support.

<link rel="apple-touch-icon"> is not created and thus also no icon on boot splash

Since the commit that checks for existence of html tags before adding them to the DOM "apple-touch-icon" links won't be created anymore.

The reason is that the code in the push() method

pwacompat/src/pwacompat.js

Lines 172 to 179 in a6ba589

if (
localName === 'link' &&
(isLinkPresent('href', attr.href) ||
(attr.sizes && isLinkPresent('sizes', attr.sizes))
)
) {
return;
}
does not check for "rel" attribute but only for "href" and "sizes". However links with href and sizes attributes have already been inserted by pwacompat while iterating the icons array of the manifest file. Because one of these icons will be the apple-touch-icon the above if will always be true.

What does ".filter(Boolean);" mean?

The safari crushed when last.removeAttribute("sizes"); // smallest is 'default', no sizes needed

117 return push('link', attr);
118 }).filter(Boolean);

Screen Shot 2019-03-12 at 7 02 37 PM

data uri for manifest

Doesn't recognize the data uri for my manifest and attempts to get using XMLHttpRequest

Invalid character in IE11

Running the demo or including pwacompat in a project yields an error with IE11. The error occurs at the following code.

if (!manifestHref) {
  throw `can't find <link rel="manifest" href=".." />'`;
}

The backticks are not accepted in IE11.

if 1 item only, Not display that item in "updateF7SmartSelect()"

Thanks for your contributions!

If I create a program as follows, the item will not be displayed in updateF7SmartSelect().

Update smart select

if (interactive()) {
library(shiny)
library(shinyMobile)

shinyApp(
ui = f7Page(
title = "My app",
f7SingleLayout(
navbar = f7Navbar(title = "Update f7SmartSelect"),
f7Button("updateSmartSelect", "Update Smart Select"),
f7SmartSelect(
inputId = "variable",
label = "Choose a variable:",
selected = "drat",
choices = colnames(mtcars)[-1],
openIn = "popup"
)
# tableOutput("data")
)
),
server = function(input, output, session) {
# output$data <- renderTable({
# mtcars[, c("mpg", input$variable), drop = FALSE]
# }, rownames = TRUE)

  observeEvent(input$updateSmartSelect, {
    updateF7SmartSelect(
      inputId = "variable",
      openIn = "sheet",
      selected = "hp",
      # choices = c("hp", "gear"),
      choices = c("hp"),  # If it changes like this
      multiple = TRUE,
      maxLength = 3
    )
  })
}

)
}

Thank you for reading it.

Build Tool

Is it possible to run this is as a CLI tool or Webpack plugin instead of at runtime?

IE Pinned Sites

IEs pinned sites provides similar features to that of a webmanifest which should be considered, specifically pinned sites metadata; including properties such as msapplication-starturl (see the metadata reference for an overview of properties).

Here is some more (possibly redundant) information/visuals:
https://blogs.msdn.microsoft.com/jennifer/2011/04/20/ie-pinned-sites-part-1-what-are-pinned-sites/

Pinned Sites is also supported in MS Edge on Windows 10.

Edit: This is already included, closing.

growing iOS support for manifest

iOS' "Add to Home Screen" feature now seems to retrieve the manifest and use several fields. This seems to be as of iOS 11.3.

  • short_name field for the title
  • start_url is respected

This happens regardless of PWACompat. The basic support doesn't use icons properly etc though, so there's still work needed.

Mistake in the README.

There is a mistake in the icons field of the manifest.webmanifest sample in the Web App Manifest field.

expected

"icons": [
    {
        "src": "res/icon-128.png",
        "sizes": "128x128"
    }
  ]

actual

"icons": [
    "src": "res/icon-128.png",
    "sizes": "128x128"
  ]

I'm sorry if you do it on purpose.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.