Full text search doesn't work when scripts are blocked
- 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
- Disable scripts using settings page - block scripts
- Open some web pages in different tabs
- Open a new tab and search for words from any of the pages in other tabs
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)
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()
}
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.
I guess global setTimeout doesn't work because it seems to use webview's setTimeout which can't work as JS disabled inside webview.
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.
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.
That's OK, the existing timeout is approximate anyways.