electron 功能请求:< webview> app-manifest-updated 事件

svdrlsy4  于 2个月前  发布在  Electron
关注(0)|答案(8)|浏览(64)

Electron <webview> 有事件用于在网页元数据发生变化时通知其父级,包括:

  • page-title-updated 用于 <title> 的变化
  • page-favicon-updated 用于 <link rel=icon> 的变化
  • did-change-theme-color 用于 <meta name=theme-color> 的变化

我想提议一个新的事件,当 Web 应用程序清单链接关系发生变化时分发:

  • app-manifest-updated 用于 <link rel=manifest> 的变化

...如 W3C Web App Manifest 规范定义的那样,并被现代渐进式 Web 应用程序使用。
事件的有效载荷可以简单地是清单的 URL,就像图标链接关系一样,或者它可以是清单 JSON 内容本身,Electron 负责以完全符合规范的方式获取清单(例如使用正确的浏览上下文和支持 HTTP 认证的清单等)。
对于现有技术,请参阅 Gecko 浏览器 API 中的 vendor-prefixed mozbrowsermanifestchanged event(类似于 Electron 的 Webview API)。
此事件的使用场景是检测当前网页是否属于一个可以安装的 Web 应用程序,并使用清单元数据将 Web 应用程序安装到 Web 应用程序运行时中。
此事件的名称可能与我在这里提议的不同,但请注意,Web 应用程序清单适用于整个 Web 应用程序或网站,该网站可能由多个页面组成,它不是严格意义上的页面元数据,而是一个 <title>

eqoofvh9

eqoofvh91#

同时,有没有解决这个问题的方法?有没有一种方法可以将脚本注入到webview上下文中,并在检测到manifest时通知父上下文?

nbysray5

nbysray52#

关于可能的解决方法,在类似的情况中,我在预加载脚本中使用了MutationObserver,并通过IPC将值报告回webContents(或webview)。这对我有效。

r6vfmomb

r6vfmomb3#

感谢@alexstrat,我会尝试一下。可以预见的是,在页面上的任何JavaScript之前运行的预加载脚本将无法访问通过JavaScript在页面加载后插入DOM中的清单链接关系。但大多数情况下应该可以正常工作。

t3psigkw

t3psigkw4#

@benfrancis 除非我误解了,否则可以。例如,您可以在预加载中执行类似 document.addEventListener("DOMContentLoaded", e => {/* do things */}) 的操作,而在 DOMContentLoaded 时将执行 /* do things */ 。对于您的情况,我建议您利用 MutationObserver

um6iljoc

um6iljoc5#

Agree with @alexstrat here - since you could enable this behavior in Electron "userland", we should probably not add a method.

bis0qfac

bis0qfac6#

我尝试使用一个 preload 脚本进行操作,似乎在很多情况下都可以获取清单URL,但我不确定是否能完全符合W3C规范来获取清单。特别是获取具有正确"manifest"上下文、CORS凭据和CSP策略的清单。似乎获取和解析清单最好由平台处理。
顺便说一下,当我在Firefox OS的Firefox浏览器中实现W3C Web应用程序清单支持时,我也遇到了同样的问题。我最初试图在应用程序本身中实现它,但我们最终意识到必须在整个平台上实现清单获取才能完全符合规范。
同意 @alexstrat 的观点 - 既然可以在Electron "userland"中启用这种行为,我们可能不应该添加一个方法。
我不太明白你的逻辑。这难道不是上面提到的所有其他示例(事件,而不是方法)的情况吗?事实上,WebView API的许多功能也是如此?什么决定了一个东西是否成为API的一部分,还是需要用户通过将JavaScript手动注入到每个页面中来解决这个问题?我更希望尽可能避免在页面中注入JS,因为这似乎有点脆弱,而且从安全Angular 来看也不太好。

ffx8fchx

ffx8fchx7#

我快速浏览了一下Chromium的逻辑,它管理着应用程序清单,看起来在幕后可能有一些我们可以接入的东西。但它没有以其他渲染器事件那样优雅的方式暴露出来 😆
https://chromium.googlesource.com/chromium/src.git/+/lkcr/content/renderer/manifest/manifest_manager.h#105

t1rydlwq

t1rydlwq8#

关于这个问题,我找到了一些基本的解决方法,适用于在DOMContentLoaded触发时存在于DOM中的清单。这覆盖了大多数网络应用。

app.html - 嵌入webview的浏览器Chrome

<script type="text/javascript" src="app.js"></script>
...
<webview preload="file://path/to/chrome/preload.js">

app.js - 浏览器Chrome代码,用于接收manifestdetected消息

webview.addEventListener('ipc-message', function(e) {
  if (e.channel == 'manifestdetected') {
    console.log('Manifest URL is ' + e.args[0]);
  }
});

preload.js - 注入到网页内容中的预加载脚本,用于发送消息

const ipcRenderer = require('electron').ipcRenderer;
var preload = function() {
  // Inform browser chrome if link to web app manifest detected
  var manifestLink = document.querySelector('link[rel="manifest"]');
  if (manifestLink) {
    ipcRenderer.sendToHost('manifestdetected', manifestLink.href);
  }
};
document.addEventListener('DOMContentLoaded', preload);

如上所述,MutationObserver可以在这一点之后检测到插入到DOM中的清单。
另外,如上所述,我认为使用这种方法实现的应用程序无法完全符合W3C Web App Manifest规范,因为实际上Electron/Chromium需要在正确的浏览上下文中获取和处理清单,并正确支持CSP、身份验证等。

相关问题