Giter VIP home page Giter VIP logo

Comments (7)

zserge avatar zserge commented on May 10, 2024 1

@jgillich It might save you a few minutes, but last time I did this check (window.external && window.external.invoke) - it didn't work with MSHTML. It's some weird magic, but MSHTML considers that invoke is undefined, yet, you can safely call it. So I ended up with actual try+call+catch: https://github.com/naivesound/glitch/blob/master/ui/app.js#L5

from webview.

zserge avatar zserge commented on May 10, 2024

To be more precise, I'm looking for a way to only inject JS code. It should happen before the page is fully loaded. The correct place for gtk-webkit would be window-object-cleared signal handler (called when window is fresh and clear, so one can add custom fields/functions to it). For Cocoa Webkit it would be didClearWindowObject, which is pretty much the same. Still looking for a MSHTML analogue.

from webview.

zserge avatar zserge commented on May 10, 2024

With MSHTML is looks like events such as DISPID_NAVIGATECOMPLETE2 and DISPID_DOCUMENTCOMPLETE arrive too late (after the scripts on the page are executed, although still before window.onload).

from webview.

zserge avatar zserge commented on May 10, 2024

Too bad, but I'm afraid I have to close this as wontfix. In MSHTML there are either events that arrive too early, so no JS context is ready and we can't evaluate javascript yet. Or there are events that arrive too late and all DOM is already rendered and all inline <script> tags are evaluated.

So instead of adding an API for this, I suggest adding the first include <script> tag that contains some app-specific window.external.invoke_('init') or some other signal that would inform the native part of the app that the page is ready and JS context is ready. It has to be copy-pasted in almost every app where you need to inject custom JS on app initialization, but I'd rather make it explicit than hide under some shady implementation.

from webview.

jgillich avatar jgillich commented on May 10, 2024

This also seems to be an issue with webkit2, eval runs after the page has loaded; with webkit1, it used to run before. Which is unfortunate because I used to shim the bound types to be able to run in a regular browser environment for development purposes.

Is there any way to make the code below work without a timeout?

view.Dispatch(func() {
  view.Eval("window.test = 'test'")
})
view.Run()
document.addEventListener('DOMContentLoaded', function () {
  console.log(window.test) // undefined

  setTimeout(function() {
    console.log(window.test) // 'test'
  }, 1000)
})

from webview.

zserge avatar zserge commented on May 10, 2024

@jgillich You are right. And it should not be an issue, because webview never guaranteed when Dispatch will be called exactly.

Correct, with webkit1 we used a window object "clear" event, which worked exactly as you described. webkit2 does not expose such events to the UI process (only to web extensions, and it's very unfortunate). So we use "load finished" event instead, which happens when page is fully loaded.

If we start sending JS before loading has finished - JS will be called before document.body exists, and it may lead to even more serious errors (well, at least that's what I have experienced while running examples).

My suggestion would be to emit your own event after your last dispatch is done, and not rely on DOMContentLoaded/window.onload. Use your own entry point. You should be able to detect whether your code runs in a browser or in a webview (I usually call window.external.invoke() and if I catch an error - it's a browser), so you may wrap it into some compatibility layer if you need.

from webview.

jgillich avatar jgillich commented on May 10, 2024

Thanks, that did the trick! For the record, here's how I did it:

view.Dispatch(func() {
  // Bind() types
  view.Eval("init()")
})

view.Run()
function isWebView() {
  try {
    window.external.invoke('');
    return true;
  } catch (e) {
    return false;
  }
}

if (!isWebView()) {
  // shim types
  init()
}

function init() {
  // start app
}

from webview.

Related Issues (20)

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.