cvzi / genius-lyrics-userscript

A userscript library to show lyrics from genius.com on other websites
GNU General Public License v3.0
14 stars 5 forks source link

What is the purpose of these codes? #16

Closed cyfung1031 closed 1 year ago

cyfung1031 commented 1 year ago

  function freshWindowFromIframe () {
    const iframe = document.body.appendChild(document.createElement('iframe'))
    iframe.style.display = 'none'
    return iframe.contentWindow
  }
  const setTimeout = function (a, b) {
    if (window.setTimeout.toString().indexOf('[native code]') !== -1) {
      return window.setTimeout(a, b)
    }
    if (top.setTimeout.toString().indexOf('[native code]') !== -1) {
      return top.setTimeout(a, b)
    }
    if (!cleanWindow && document.body) {
      cleanWindow = freshWindowFromIframe()
    }
    if (cleanWindow) {
      return cleanWindow.setTimeout(a, b)
    } else {
      return window.setTimeout(a, b)
    }
  }
  const setInterval = function (a, b) {
    if (window.setInterval.toString().indexOf('[native code]') !== -1) {
      return window.setInterval(a, b)
    }
    if (top.setInterval.toString().indexOf('[native code]') !== -1) {
      return top.setInterval(a, b)
    }
    if (!cleanWindow && document.body) {
      cleanWindow = freshWindowFromIframe()
    }
    if (cleanWindow) {
      return cleanWindow.setInterval(a, b)
    } else {
      return window.setInterval(a, b)
    }
  }
  const clearTimeout = function (a, b) {
    if (window.clearTimeout.toString().indexOf('[native code]') !== -1) {
      return window.clearTimeout(a, b)
    }
    if (top.clearTimeout.toString().indexOf('[native code]') !== -1) {
      return top.clearTimeout(a, b)
    }
    if (!cleanWindow && document.body) {
      cleanWindow = freshWindowFromIframe()
    }
    if (cleanWindow) {
      return cleanWindow.clearTimeout(a, b)
    } else {
      return window.clearTimeout(a, b)
    }
  }
  const clearInterval = function (a, b) {
    if (window.clearInterval.toString().indexOf('[native code]') !== -1) {
      return window.clearInterval(a, b)
    }
    if (top.clearInterval.toString().indexOf('[native code]') !== -1) {
      return top.clearInterval(a, b)
    }
    if (!cleanWindow && document.body) {
      cleanWindow = freshWindowFromIframe()
    }
    if (cleanWindow) {
      return cleanWindow.clearInterval(a, b)
    } else {
      return window.clearInterval(a, b)
    }
  }

I cannot notify any declaration of setTimeout, setInterval, clearTimeout, and clearInterval in the script. What is the purpose of these coding?

cvzi commented 1 year ago

It is necessary on Spotify, because the Spotify page overwrites setTimeout and the other functions. This is a way to get the built-in functions back. I don't know if there is a simpler way to do it, but this works.

cyfung1031 commented 1 year ago

It is necessary on Spotify, because the Spotify page overwrites setTimeout and the other functions. This is a way to get the built-in functions back. I don't know if there is a simpler way to do it, but this works.

Understand, but why you cannot use the modified setTimeout? I checked that its implementation is the same as the native. Perhaps Spotify just want to do some logging.

cvzi commented 1 year ago

I have not checked it since I added that. Maybe it has changed. At the time, their implementation was really slow, because it send and waited for a request to the Spotify server before running.

cyfung1031 commented 1 year ago

I have not checked it since I added that. Maybe it has changed. At the time, their implementation was really slow, because it send and waited for a request to the Spotify server before running.

I have figured out that Spotify uses two different implementations of setTimeout.

First is a fake window object and fake setTimeout / setInterval.

Screen Shot 2022-12-15 at 21 58 36

Second one can work as normal although it is modified.

Screen Shot 2022-12-15 at 21 59 06