min icon indicating copy to clipboard operation
min copied to clipboard

Full text search doesn't work when scripts are blocked

Open gkrishnaks opened this issue 1 year ago • 7 comments

  • Min Version: 1.33.0
  • Operating system: Windows 10

Expected Behavior

Full text search to work when scripts are blocked via settings page 'block scripts'

Actual Behavior

Full text search didn't work when scripts are blocked.

To Reproduce

  1. Disable scripts using settings page - block scripts
  2. Open some web pages in different tabs
  3. Open a new tab and search for words from any of the pages in other tabs

gkrishnaks avatar Sep 15 '24 00:09 gkrishnaks

It seems that when JS is disabled, calling setTimeout in the preload script doesn't work - if I add this code, I only see "before" in the console, which is quite strange:

console.log("before")
setTimeout(function() {
  console.log("after")
}, 500)

(this breaks full-text search because the text extraction is wrapped in a setTimeout)

PalmerAL avatar Sep 15 '24 04:09 PalmerAL

Ok, since setTimeout doesn't work in preload script when JS disabled, I tried the below and used it in textExtractor's setTimeout usage. It resolved the issue for full text search when JS disabled in settings page.

There are some more setTimeout usages in preload scripts...will need to investigate if those instances can also be replaced with this custom setTimeout

In js/preload/default.js

const customTimer = {}
customTimer.delay = ms => new Promise(resolve => {
  const before = Date.now()
  const stopAt = before + ms
  while (Date.now() < stopAt) { };
  resolve()
})

customTimer.setTimeout = async (fn, ms) => {
  await customTimer.delay(ms)
  fn()
}

gkrishnaks avatar Sep 16 '24 17:09 gkrishnaks

Wouldn't that block the rest of the preload (and potentially the whole page) while it's running?

I think my preference would be to just run the text extraction immediately if we're in this state. I wonder if there are other things that are broken still though; I'm thinking that disabling JS execution but still running a preload script probably isn't intended to be supported by Chromium.

PalmerAL avatar Sep 17 '24 01:09 PalmerAL

I guess global setTimeout doesn't work because it seems to use webview's setTimeout which can't work as JS disabled inside webview.

gkrishnaks avatar Sep 17 '24 07:09 gkrishnaks

It looks like requestAnimationFrame works, so we could do something hacky like this:

function iter(count = 0) {
  if (count === 200) {
    console.log("dispatch")
  }
  requestAnimationFrame(() => {iter(count + 1)})
}

iter();

There's also the node require("timers") API, but that doesn't seem to work for me either.

It seems like there's potentially more features of the preload broken also though, so I'm not convinced the text extraction will actually work correctly even if we do this. For example, if I try to reproduce this in electron-quick-start, my preload script actually doesn't run at all, until I open the devtools and reload, then it does.

PalmerAL avatar Sep 25 '24 17:09 PalmerAL

Also tried writing a custom timeout logic using window.requestIdleCallback, inside that preload script. It works but the timer won't be accurate, will be approximate.

gkrishnaks avatar Sep 25 '24 17:09 gkrishnaks

That's OK, the existing timeout is approximate anyways.

PalmerAL avatar Sep 28 '24 00:09 PalmerAL