- 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
andwindow.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__()
}