internetarchive / bookreader

The Internet Archive BookReader
https://openlibrary.org/dev/docs/bookreader
GNU Affero General Public License v3.0
974 stars 416 forks source link

Book reader breaks after I include plugin.search.js in project.json includes section of my Angular project. #1344

Open parultrantor opened 2 days ago

parultrantor commented 2 days ago

Reader does not work after including search plugin

The reader works if I do not include the search plugin but as soon as I include the search plugin the reader breaks with the following error:

ERROR TypeError: Cannot read properties of undefined (reading 'dom') at Qe. (global:scripts.js:29493:22027) at r2. (global:scripts.js:29490:481395) at n3.value (global:scripts.js:29490:344009) at Qe.l2 (global:scripts.js:29490:481219) at Qe.init (global:scripts.js:29490:488745) at Qe.init (global:scripts.js:29493:21531) at _ImageReaderComponent.initializeBookReader (image-reader.component.ts:98:13) at HTMLDocument. (image-reader.component.ts:35:12) at _ZoneDelegate.invokeTask (zone.js:403:31) at core.mjs:15287:55

This is the piece of code that throws this error:

return this.searchView.dom.toolbarSearch && t.find(".BRtoolbarSectionInfo").after(this.searchView.dom.toolbarSearch),

This code is a part of plugin.search.js

Screenshot 2024-09-30 at 6 37 47 PM

I am new to this plugin and I was not able to find much documentation on how to make search work I would really appreciate any help on the same as I am stuck on this for more than a week.

cdrini commented 2 days ago

Hello, apologies, the examples in our readme are out-of-date and could use some updating. I believe the error you're seeing is a result of not having the web component JS loaded. You can see a more concrete example that should work here: https://github.com/internetarchive/bookreader/pull/1321/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5 . But I'd need to see a bit more of how you're importing/initializing BookReader to say for certain!

Note the search plugin has a few spots where it makes assumptions about specific Internet Archive endpoints, so you might need to modify the code. Or open a PR to add any options you see missing :)

parultrantor commented 1 day ago

Thanks @cdrini, It helped I am however facing a new problem now. I have added the search plugin but it is not getting properly initialized I am getting the following error

image-reader.component.ts:98 ERROR TypeError: Cannot read properties of undefined (reading 'dom') at Qe. (plugin.search.js:107:25) at Object.defineProperty.set.r. (classes.js:31:27) at n.value (Toolbar.js:73:29) at Qe.l (classes.js:19:17) at Qe.init (BookReader.js:538:10) at Qe.init (plugin.search.js:76:12) at image-reader.component.ts:99:15 at timer (zone.js:2402:41) at _ZoneDelegate.invokeTask (zone.js:403:31) at core.mjs:15287:55

It is originating from the following line

https://github.com/internetarchive/bookreader/blob/0a244048e328b6577d52c6a05b705c921032db79/src/plugins/search/plugin.search.js#L103

BookReader.prototype.init is getting called after BookReader.prototype.buildToolbarElement

Am I missing something, can you please provide a working example of search?

Thanks in advance!

cdrini commented 1 day ago

Can you include how you import bookreader? The order that the plugins are imported can have an impact here!

parultrantor commented 1 day ago

Sure here is my complete index.html file

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Bookreader Demo</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <script type="text/javascript" src="https://polyfill.io/v3/polyfill.min.js?features=es2015%2Ces5%2CglobalThis"></script>
    <script type="text/javascript" src="https://unpkg.com/lit@2.1.2/polyfill-support.js"></script>
    <script src="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/jquery-3.js"></script>
    <script type="text/javascript" src="https://unpkg.com/@webcomponents/webcomponentsjs@2.2.10/webcomponents-bundle.js"></script>

    <!-- JS dependencies -->
    <script src="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/webcomponents-bundle.js"></script>

    <!-- BookReader and  plugins -->
    <link rel="stylesheet" href="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/BookReader.css" />
    <script src="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/BookReader.js"></script>
    <script src="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/plugins/plugin.url.js"></script>
    <script src="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/plugins/plugin.search.js"></script>
    <!-- BookReader wrapper web component -->
    <script type="module" src="https://unpkg.com/@internetarchive/bookreader@5.0.0-80/BookReader/ia-bookreader-bundle.js"></script>
  </head>
  <body>
    <bookreader-demo-root></bookreader-demo-root>
  </body>
</html>
parultrantor commented 1 day ago

Also for reference here is my component file that initializes the reader

import { AfterViewInit, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';

declare const BookReader: any;
declare const document: any;
@Component({
  selector: 'bookreader-demo',
  standalone: true,
  imports: [CommonModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  styleUrl: './bookreader-demo.component.scss',
  templateUrl: './bookreader-demo.component.html',
})
export class BookreaderComponent implements AfterViewInit {
  private br: any;
  searchTerm: string= '';

  constructor() {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    document.addEventListener('DOMContentLoaded', () => {
      this.initializeBookReader();
   });
  }
  initializeBookReader(): void {
    const options = {
      getNumLeafs: () => 40,
      getPageWidth: () => 800,
      getPageHeight: () => 1200,
      getPageURI: (index: number) => `/assets/BK-000001/${index + 1}.jpg`,
      getPageSide: (index: number) => (index % 2 === 0 ? 'R' : 'L'),
      pageProgression: 'lr',
      getSpreadIndices: function (pindex: number) {
        const spreadIndices: (number | null)[] = [null, null];
        if (this.pageProgression === 'rl') {
          if (this.getPageSide(pindex) === 'R') {
            spreadIndices[1] = pindex;
            spreadIndices[0] = pindex + 1;
          } else {
            spreadIndices[0] = pindex;
            spreadIndices[1] = pindex - 1;
          }
        } else {
          if (this.getPageSide(pindex) === 'L') {
            spreadIndices[0] = pindex;
            spreadIndices[1] = pindex + 1;
          } else {
            spreadIndices[1] = pindex;
            spreadIndices[0] = pindex - 1;
          }
        }
        return spreadIndices;
      },
      getPageNum: (index: number) => index + 1,
      bookTitle: 'BookReader Advanced Demo',
      bookUrlText: 'Back to Demos',
      thumbnail: '//archive.org/download/BookReader/img/page014.jpg',
      metadata: [{ label: 'Title', value: 'Open Library BookReader Presentation' }],
      imagesBaseURL: '/assets/BookReader/images/',
      ui: 'full',
      enableExperimentalControls: true,
      showToolbar: true,
      showNavbar: true,
      search: 'visible',
      sideBar: 'visible',
      bookmarks: 'visible',
      share: 'visible',
      enableSearch: true,
      enableBookmark: true,
      enableFullscreen: true,
      enableShare: true,
      enableSidebar: true,
      enableDownload: true,
      searchInsidePostTag: "}}}",
      searchInsidePreTag: "{{{",
      searchInsideProtocol: "https",
      searchInsideUrl: "/fulltext/inside.php",
      initialSearchTerm: ""
    };
    this.br = new BookReader(options);
    this.br.init();
  }

}

And here is the component HTML

<ia-bookreader>
  <div id="BookReader" class="BookReader" slot="main"></div>
  <noscript>
    <p>
      The BookReader requires JavaScript to be enabled. Please check that
      your browser supports JavaScript and that it is enabled in the
      browser settings.
    </p>
  </noscript>
</ia-bookreader>

I also request that you provide me with the correct order to include the plugins as I intend to use more of them once the search is sorted.

Warm Regards, Parul Shukla

cdrini commented 6 hours ago

Ah, I investigated and there appears to be a bug with the toolbar option and the search plugin. If you set showToolbar: false, that will fix the issue.

They should be in this order (although with the full unpkg links, of course!)

    <script src="../BookReader/plugins/plugin.search.js"></script>
    <script src="../BookReader/plugins/plugin.chapters.js"></script>
    <script src="../BookReader/plugins/plugin.tts.js"></script>
    <script src="../BookReader/plugins/plugin.url.js"></script>
    <script src="../BookReader/plugins/plugin.autoplay.js"></script>
    <script src="../BookReader/plugins/plugin.resume.js"></script>
    <script src="../BookReader/plugins/plugin.archive_analytics.js"></script>
    <script src="../BookReader/plugins/plugin.text_selection.js"></script>