Friday, June 3, 2022

Calibre-Web epub url churn

I am using calibre-web to view epub documents, with Firefox plugin zhongwen for lookup of Chinese characters.

The zhongwen plugin selects text matching dictionary entries as the cursor moves over the document and opens a popup to display the matching definitions.

The published zhongwen plugin doesn't work with epub documents displayed by calibre-web because it doesn't handle the iframe that the epub document appears in, so I am using a modified version of the plugin: ig3/zhongwen.

This modified version of the plugin works. I can view Chinese epub documents with lookup of the Chinese characters, which is very helpful for my Chinese study.

However, every time the zhongwen plugin changes the selected text, the epub reader updates the URL with a new epubcfi that specifies the selected text. This churn of the URL results in many browser history entries. When I look for something in my browser history, I have to scroll over thousands of these history entries to find what I want.

I don't was a browser history entry every time zhongwen selects text.

With a bit of poking about in the calibre-web source, I found that it uses the Futurepress reader and epub.js libraries to render epub documents.

The epub.js library emits events when selection changes but doesn't have code that would update browser history.

The reader does have code that updates browser history on selection change.

Looking at ~/.local/lib/python3.7/site-packages/calibreweb/cps/static/js/libs/reader.min.js I see "history:!0", which appears to be setting default value of the "history" option which determines if history is updated.

I changed "history:!0" to "history:!1", reloaded the epub document and now the URL is not changed when zhongwen plugin selects text.

But now there are no updates to the URL at all: not even when I move to a different page. So I have gone from too much history to too little.

So, I grabbed a copy of the non-minified reader and edited the function that updates the URL to:

PUBJS.Reader.prototype.selectedRange = function(cfiRange){
  var cfiFragment = "#"+cfiRange;

  // Update the History Location
  if(this.settings.history &&
      window.location.hash != cfiFragment &&
    cfiFragment.indexOf(',') === -1
  ) {
    // Add CFI fragment to the history
    history.pushState({}, '', cfiFragment);
    this.currentLocationCfi = cfiRange;
  }
};

The addition is "cfiFragment.indexOf(',') === -1", which prevents the update if the fragment includes a comma, which it does if it is a "RANGE" of text.

With this change, I get URL updates / history when I use the page navigation but no URL updates / history when text is selected. 

This seems a reasonable compromise and, thus far, everything works. The change hasn't broken anything that I have noticed.

 

No comments:

Labels