Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LoadStarted WebView event doesn't trigger on Android #15

Open
AlexTiehuis opened this issue Feb 13, 2020 · 2 comments
Open

LoadStarted WebView event doesn't trigger on Android #15

AlexTiehuis opened this issue Feb 13, 2020 · 2 comments

Comments

@AlexTiehuis
Copy link

I am using [loadStarted] and [loadFinished] events in a Webview in NativeScript/Angular, among other things, to start and stop a spinner. On my iPhone both events are triggered as soon as navigation starts and ends. On my Android phone the loadStarted event isn't triggered causing the spinner to malfunction. Looks like only links with tel:, mailto: and loc: trigger the [loadStarted] event.

In node module [webview-utils.android.js], function [onPageStarted], line 47 there is this If statement: if (!isHttpRequest || ++this.startEventCount === 1) The ++ increments this.startEventCount while testing === 1 which will only be true the first time a pageLoad starts. In my opinion this causes the loadStarted event to be called only once (unless the url starts with [tel:, mailto: or loc:]) Having fixed this locally, I noticed that the loadStarted event is triggered too late. Showing the spinner only a few milliseconds before the webpage finishes loading.

Non-trigger and too late trigger of [loadStarted] both don't work for my App.
Are there solutions to these problems?

XML:

<ActionBar #webviewActionbar title="Facilitor" flat="true">
    <ActionItem (tap)="onQrScanTap()" ios.position="right" ios.systemIcon="15" android.systemIcon="ic_menu_camera">
    </ActionItem>
</ActionBar>
<GridLayout rows="*">
    <WebView row="0" #loginView (loaded)="webviewLoaded($event);" (loadStarted)="webviewTrigger($event)" (loadFinished)="onLoadFinished($event)" (doubleTap)="onDoubleTap($event)" (swipe)="onSwipe($event)" [src]="webViewSrc" ></WebView>
    <TextField row="0" [(ngModel)]="registerModel.push_action" #pushActionModel="ngModel" autocorrect="false"
    autocapitalizationType="none" [visibility]="'collapse'" (textChange)="navigateToAction()"></TextField>
    <ActivityIndicator (loaded)="onSpinnerLoaded($event)" rowSpan="2" [busy]="isBusy" (busyChange)="onBusyChanged($event)" width="100" height="100"></ActivityIndicator>
</GridLayout>

TypeScript:

  private onLoadFinished(args: any) {
    console.log("== onLoadFinished ==");
    this.isBusy = false;
  }
  private webviewTrigger(args: any) {
    console.log("== webviewTrigger ==");
    var webView: WebView = <WebView>args.object;
    console.log(webView);
    // get location
    if (args.url.startsWith('loc:')) {
      let arr = args.url.split(":");
      this.registerModel.push_action = this.registrationService.composeUrl() + arr[1] + "?longitude=" + this.lastLocation.longitude + "&latitude=" + this.lastLocation.latitude;
      this.navigateToAction();
      webView.reload();
      return;
    // handle mailto: and tel:
    } else if (args.url.startsWith('mailto:') || args.url.startsWith('tel:')) {
      utils.openUrl(args.url);
      webView.reload();
      return;
    }
    // start spinner
    this.isBusy = true;
  }

Terminal log after tapping some links:

JS: == onNavigatingTo ==
chromium: [INFO:library_loader_hooks.cc(51)] Chromium logging enabled: level = 0, default verbosity = 0
JS: == webviewLoaded ==
JS: WebView(44)
JS: == setHTTPHeader ==
JS: == onSpinnerLoaded ==
JS: == onNavigatedTo ==
JS: == webviewTrigger ==
JS: WebView(44)
JS: indicator.busy changed to: true
JS: ===Location===
JS: == onLoadFinished ==
JS: indicator.busy changed to: false
JS: == onLoadFinished ==
JS: == onLoadFinished ==
JS: == onLoadFinished ==
@AlexTiehuis
Copy link
Author

I adjusted the webview-utils.android.js somewhat with the little knowledge I have about NativeScript. The [onLoadStarted] event triggers at the right time with below code:

    WebViewUtils.prototype.shouldOverrideUrlLoading = function(webView, urlOrWebResourceRequest) {
        console.log("shouldOverrideUrlLoading");
        var url = typeof urlOrWebResourceRequest === "string" ? urlOrWebResourceRequest : urlOrWebResourceRequest.getUrl().toString();
        var headersAdded = this.headersAddedTo.has(url);
        var isHttpRequest = url.indexOf("http") === 0;
        if (!isHttpRequest || (headersAdded && WebViewUtils.wv) || ++this.startEventCount > 1) {
            webview_utils_common_1.onLoadStarted(WebViewUtils.wv, url, undefined);
        }
        webView.loadUrl(url, this.getAdditionalHeadersForUrl(url));
        return true;
    };
    WebViewUtils.prototype.onPageStarted = function(webView, url, favicon) {
        _super.prototype.onPageStarted.call(this, webView, url, favicon);
        var headersAdded = this.headersAddedTo.has(url);
        var isHttpRequest = url.indexOf("http") === 0;
        if (isHttpRequest && !headersAdded) {
            ++this.startEventCount;
            this._view.android.loadUrl(url, this.getAdditionalHeadersForUrl(url));
            if (WebViewUtils.wv) {
                webview_utils_common_1.onLoadStarted(WebViewUtils.wv, url, undefined);
            }
        }
    };

@AlexTiehuis
Copy link
Author

Not sure why this issue was closed. Can't remember having it closed. Probably mis-clicked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant