Skip to content

Instantly share code, notes, and snippets.

@Wizek
Created October 24, 2020 17:28
Show Gist options
  • Save Wizek/897492895e41d9349aec51e5a9389f94 to your computer and use it in GitHub Desktop.
Save Wizek/897492895e41d9349aec51e5a9389f94 to your computer and use it in GitHub Desktop.
Chrome Extensions Manager utility functions

It can be ran on chrome://extensions/ (tested on chrome version 86.0.4240.75)

Right now this supports basic functions, such as import, export, turn all on, turn all off.

It export-imports in JSON format, like this:

[
  {
    "enabled": true,
    "name": "Highlight open links",
    "id": "apakhhhanmjcpjnejnpomikalenlccof",
    "version": "0.1.0",
    "dev": true
  },
  {
    "enabled": true,
    "name": "Inter-tab history",
    "id": "clmalbcbanllhnjliafhpgfmcbfkmajj",
    "version": "0.4.0",
    "dev": true
  }
]

I created this when I wanted to track down a misbehaving extension out of 40 enabled. I hoped to create a binary set-search algorithm on top of this, where this automatically and efficiently narrows down exactly which single or combination of extensions cause an error, but alas that is not yet supported.

function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function getAllExtensionEls () {
const ourRootEl = document.querySelector('extensions-manager').shadowRoot.querySelector('extensions-item-list').shadowRoot
const allExtensionEls = [...ourRootEl.querySelectorAll('extensions-item')]
return allExtensionEls
}
function run () {
console.log(`init`)
exportAll()
// importAll()
// enableAll()
}
function exportAll () {
const allExtensionEls = getAllExtensionEls()
let enabledCount = 0
const out = allExtensionEls.map(x => {
let r = x.shadowRoot
let en1 = isEnabledEl(r)
if (en1) enabledCount++
return {
enabled: en1,
name: getName(r),
id: x.id,
version: r.querySelector('#version').innerText,
dev: r.querySelector('#card').classList.contains('dev-mode'),
}
})
let count = allExtensionEls.length
console.log({count, enabledCount})
// console.log(out)
// copy(out)
// download(`chrome extension export ${new Date().toISOString()}.json`, JSON.stringify(out, null, 2))
}
let adjustAll = predicate => () => {
const allExtensionEls = getAllExtensionEls()
allExtensionEls.map(x => {
let r = x.shadowRoot
let en1 = isEnabledEl(r)
let p = predicate(x.id, r, x)
if ((p == 'shouldEnable' && !en1) || (p == 'shouldDisable' && en1)) {
r.querySelector('#enableToggle').click()
}
})
}
let getName = r => r.querySelector('#name').innerText
let isEnabledEl = r => {
let en1 = r.querySelector('#enableToggle').ariaPressed == "true"
let en2 = r.querySelector('#card').classList.contains('enabled')
if (en1 != en2) {console.warn({txt: 'enabled state mismatch', en1, en2, r, x})}
return en1
}
let disableAll = adjustAll(_ => 'shouldDisable')
let enableAll = adjustAll(_ => 'shouldEnable')
let importAll = list => {
adjustAll((id, r) => {
let match = list.find(e => id == e.id)
if (!match) {
console.warn({txt: 'Import list does not specify what to do about this installed extension:', id: e.id, name: getName(r)})
return 'shouldLeaveAsIs'
}
return match.enabled ? 'shouldEnable' : 'shouldDisable'
})()
}
let hideAllDisabled = adjustAll((id, r, x) => {
if (!isEnabledEl(r)) {
x.style.display = 'none'
}
return 'shouldLeaveAsIs'
})
let unhideAllDisabled = adjustAll((id, r, x) => {
if (!isEnabledEl(r)) {
x.style.display = ''
r.querySelector('#card').style.display = ''
}
return 'shouldLeaveAsIs'
})
// unhideAllDisabled()
// hideAllDisabled()
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment