cordova-plugin-inappbrowser icon indicating copy to clipboard operation
cordova-plugin-inappbrowser copied to clipboard

Beforeload event is not fired the 2,4,6 time.

Open aadiver opened this issue 3 years ago • 4 comments

Bug Report

Problem

beforeload is called at every second click

What is expected to happen?

beforeload should be called at every click

What does actually happen?

First time you click on a link in the InAppBrowser I get the following events: beforeload loadstart loadstop When clicking a second time on the same link or another link I get only the following events: loadstart loadstop When clicking a third time on a link I get again the beforeload event beforeload loadstart loadstop

Command or Code

import {
  Component,
  NgZone,
  OnInit,
  TemplateRef,
  ViewChild,
} from '@angular/core';
import { TranslateService, TranslationChangeEvent } from '@ngx-translate/core';
import { ConfigService } from '../core/services/config.service';
import { ModalDismissReasons, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { AuthenticationService } from '../core/services/authentication.service';

export const LOCAL_TOKEN_STORAGE = 'ACCOUNT_API_TOKEN';
declare var cordova: any;

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent implements OnInit {
  numbers: number[];
  public searchText: string;
  public applictionList: Array<{
    number: number;
    name: string;
    description: string;
  }> = [];
  src: any;
  iabRef: any = null;
  closeModal: string;
  @ViewChild('modalData', { static: true }) modalData: TemplateRef<any>;

  constructor(
    private translate: TranslateService,
    public readonly configService: ConfigService,
    private modalService: NgbModal,
    public authService: AuthenticationService,
    private ngZone: NgZone
  ) {
    this.translate.onLangChange.subscribe((event: TranslationChangeEvent) => {
      this.createApplicationList();
    });
  }

  ngOnInit(): void {
    this.createApplicationList();
  }

  // function to return list of numbers from 0 to n-1
  numSequence(n: number): Array<number> {
    return Array(n);
  }

  iabBeforeLoad(event: any, callback: any): void {
    console.log(event.type + ' - ' + event.url);
    console.log('   callback: ' + callback);

    // If the URL being loaded is a PDF
    if (event.url.match('.pdf') || event.url.match('.ashx')) {
      // Open PDFs in system browser (instead of InAppBrowser)
      // cordova.InAppBrowser.open(event.url, '_system');
      this.ngZone.run(() => {
        this.iabRef.hide();
        this.src = event.url;
        this.triggerModal(this.modalData);
      });
      //
    } else {
      // Invoke callback to load this URL in InAppBrowser
      callback(event.url);
    }
  }

  iabLoadStart(event: any): void {
    console.log(event.type + ' - ' + event.url);
  }

  iabLoadStop(event: any): void {
    console.log(event.type + ' - ' + event.url);

    this.iabRef.executeScript({
      code: `
        var links = document.getElementsByTagName("a");
        console.log(links);
        for (var i = 0; i < links.length; i++) {
          if(links[i].href.indexOf('.pdf') > -1 || links[i].href.indexOf('.ashx') > -1)
          {
            links[i].target = "_self";
            console.log("change target", links[i]);
          }
        }
        `,
    });
  }

  iabLoadError(event: any): void {
    console.log(event.type + ' - ' + event.message);
  }

  iabClose(event: any): void {
    console.log(event.type);
    // this.iabRef.removeEventListener(
    //   'beforeload',
    //   (params: any, callback: any) => this.iabBeforeLoad(params, callback)
    // );
    // this.iabRef.removeEventListener('loadstart', (params: any) =>
    //   this.iabLoadStart(params)
    // );
    // this.iabRef.removeEventListener('loadstop', (params: any) =>
    //   this.iabLoadStop(params)
    // );
    // this.iabRef.removeEventListener('loaderror', (params: any) =>
    //   this.iabLoadError(params)
    // );
    // this.iabRef.removeEventListener('exit', (params: any) =>
    //   this.iabClose(params)
    // );
  }

  openUrl(url: string): void {
    const translatedUrl = this.translate.instant(url);
    if (this.configService.isApp()) {
      // Open InAppBrowser on initial page
      this.iabRef = cordova.InAppBrowser.open(
        translatedUrl,
        '_blank',
        'location=yes,beforeload=yes'
      );

      // Add beforeload event handler which is called before each new URL is loaded into the InAppBrowser Webview
      this.iabRef.addEventListener('beforeload', (params, callback) =>
        this.iabBeforeLoad(params, callback)
      );

      this.iabRef.addEventListener('loadstart', (params) =>
        this.iabLoadStart(params)
      );

      this.iabRef.addEventListener('loadstop', (params) =>
        this.iabLoadStop(params)
      );

      this.iabRef.addEventListener('loaderror', (params) =>
        this.iabLoadError(params)
      );

      this.iabRef.addEventListener('exit', (params) => this.iabClose(params));
    } else {
      window.open(translatedUrl, '_blank');
    }
  }

  createApplicationList(): void {
    this.applictionList = [];

    for (let i = 1; i <= 14; i++) {
      this.applictionList.push({
        number: i,
        name: this.translate.instant('Applications.App' + i + 'Name'),
        description: this.translate.instant(
          'Applications.App' + i + 'Description'
        ),
      });
    }
  }

  triggerModal(content): void {
    console.log('triggerModal is called');
    this.modalService
      .open(content, {
        ariaLabelledBy: 'modal-basic-title',
        windowClass: 'custom-modal',
      })
      .result.then(
        (res) => {
          this.closeModal = `Closed with: ${res}`;
          this.ngZone.run(() => {
            this.iabRef.show();
          });
        },
        (res) => {
          this.closeModal = `Dismissed ${this.getDismissReason(res)}`;
          this.ngZone.run(() => {
            this.iabRef.show();
          });
        }
      );
  }

  private getDismissReason(reason: any): string {
    if (reason === ModalDismissReasons.ESC) {
      return 'by pressing ESC';
    } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
      return 'by clicking on a backdrop';
    } else {
      return `with: ${reason}`;
    }
  }

  // PDF ‘downloaden’ als een bytearray
  getPdfXhr(url: string, success: (array) => void, fallback: Function) {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'arraybuffer';
    xhr.setRequestHeader(
      'Authorization',
      `Bearer ${localStorage.getItem(LOCAL_TOKEN_STORAGE)}`
    );

    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.onload = () => {
      try {
        const arrayBufferView = xhr.response;
        success(arrayBufferView);
      } catch (error) {
        error('Could not get document ' + error);
      }
    };

    xhr.send(`\"${url}\"`);
  }
}

Environment, Platform, Device

Android

Version information

"cordova-plugin-inappbrowser": "^5.0.0"

aadiver avatar Oct 11 '21 14:10 aadiver

any ideas? i have the same problem, when url contains a file (.pdf, .docx..), the loadstop event is fired only after a second click.

FabricioCapelini avatar Jan 19 '22 15:01 FabricioCapelini

I have the same problem. Clues ?

jorisck avatar Jun 27 '22 10:06 jorisck

https://github.com/apache/cordova-plugin-inappbrowser/pull/755

monove avatar Jun 27 '22 20:06 monove

I've tested it with

  1. cordova plugin add cordova-plugin-inappbrowser which installs version 5.0.0
  2. and also with the latest version from the master branch in github cordova plugin add https://github.com/apache/cordova-plugin-inappbrowser but same behavior: the beforeload is only called once at the two times.

Is this cordova-plugin-appbrowser still be used because I see at the following link in the npm store https://www.npmjs.com/package/cordova-plugin-inappbrowser?activeTab=versions that the latest published version is from 2 years ago?

aadiver avatar Mar 03 '23 14:03 aadiver