0
  • I am working on a Google Chrome extension which adds a DevTools panel.
  • Main purpose of this extension is to help debug Adobe Analytics, Google Analytics and Tealium iQ requests.
  • A website which integrates with Tealium iQ will have the window.utag object.
  • window.utag object contains two functions, window.utag.view and window.utag.link, which I would like to override using a decorator pattern. I would like to only add logging to the original functionality.
  • My extension is using manifest version 2 and I am currently migrating it to use manifest version 3.
  • Using manifest version 2, I was able to utilise a content script to add a script tag onto the page (https://github.com/temelm/tealman/blob/master/src/utagviewandlinkwithlogging.js). However, I had to add my logic as a string by setting the text attribute of the script tag.
  • Using manifest version 3, below is what I have tried which does not seem to work:

manifest.json

{
  "manifest_version": 3,
  "name": "Tealman",
  "version": "3.0.1",
  "description": "Extends Chrome DevTools to capture data sent to Adobe Analytics, Google Analytics and Tealium iQ.",
  "icons": {
    "128": "images/icon-128.png"
  },
  "background": {
    "service_worker": "background.js"
  },
  "devtools_page": "devtools/devtools.html",
  "permissions": ["scripting"],
  "host_permissions": ["<all_urls>"]
}

background.js

try {
  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (changeInfo.status === 'complete') {
      chrome.scripting.executeScript({
        target: { tabId },
        files: ['content-scripts/utagviewandlinkwithlogging.js']
      })
    }
  })
} catch (error) {
  console.error(error)
}

utagviewandlinkwithlogging.js

if (typeof __TEALMAN_HOOK__ === 'undefined') {
  const __TEALMAN_HOOK__ = () => {
    function decorateWithLogging (fn, logMessagePrefix = '') {
      return function () {
        const message = {...arguments[0]}
        console.group('[Tealman]', logMessagePrefix)
        console.log(message)
        console.groupEnd()
        const result = fn.apply(this, arguments)
        return result
      }
    }

    const delay = 125
    const maxRetries = 32
    let retries = 0

    function wait () {
      if (window.utag && typeof window.utag.view === 'function' && typeof window.utag.link === 'function') {
        window.setTimeout(() => {
          window.utag.view  = decorateWithLogging(window.utag.view, 'utag.view')
          window.utag.link  = decorateWithLogging(window.utag.link, 'utag.link')
        }, delay)
      } else {
        retries++
        if (retries < maxRetries) {
          window.setTimeout(wait, delay)
        }
      }
    }

    wait()
  }
  __TEALMAN_HOOK__()
}
temelm
  • 826
  • 4
  • 15
  • 34

0 Answers0