Debugging source files using chrome extension - javascript

I am trying to control the debugger using Chrome Extension.
I am using devtools-protocol and chrome extension documentation, but I have no idea how to implement them as I have not seen any samples of the methods in use. I used the sample extension from here which shows how to pause and resume the debugger only, but that's absolutely no use to me. I tried to implement some methods in the sample, but nothing happens.
function onDebuggerEnabled(debuggeeId) {
chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
lineNumber: 45825,
url: 'full https link to the js file from source tab'
});
}
The problem is that the js file I am trying to debug is loaded from the website inside the sources tab and it's huge, we talking 150k+ lines after its been formatted and it takes some time to load.
Now can anyone tell me how to simply add a break point inside the js file from the sources (USING CHROME EXTENSION) so it could be triggered on action which will then stops the debugger so I could change values etc?

Maybe you are placing wrong breakpoint location (formatted source), try working with original source and add columnNumber: integer
and here working version JavaScript pause/resume -> background.js:
install this extension
open https://ewwink.github.io/demo/Debugger.setBreakpointByUrl.html
click debugger pause button
click button "Debug Me!"
it will hit breakpoint on https://ewwink.github.io/demo/script.js at line 10
click debugger continue button, you will see message variable "hijacked..."
the code:
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// mod by ewwink
var attachedTabs = {};
var version = "1.1";
chrome.debugger.onEvent.addListener(onEvent);
chrome.debugger.onDetach.addListener(onDetach);
chrome.browserAction.onClicked.addListener(function(tab) {
var tabId = tab.id;
var debuggeeId = {
tabId: tabId
};
if (attachedTabs[tabId] == "pausing")
return;
if (!attachedTabs[tabId])
chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
else if (attachedTabs[tabId])
chrome.debugger.detach(debuggeeId, onDetach.bind(null, debuggeeId));
});
function onAttach(debuggeeId) {
if (chrome.runtime.lastError) {
alert(chrome.runtime.lastError.message);
return;
}
var tabId = debuggeeId.tabId;
chrome.browserAction.setIcon({
tabId: tabId,
path: "debuggerPausing.png"
});
chrome.browserAction.setTitle({
tabId: tabId,
title: "Pausing JavaScript"
});
attachedTabs[tabId] = "pausing";
chrome.debugger.sendCommand(
debuggeeId, "Debugger.enable", {},
onDebuggerEnabled.bind(null, debuggeeId));
}
function onDebuggerEnabled(debuggeeId) {
chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
lineNumber: 10,
url: 'https://ewwink.github.io/demo/script.js'
});
}
function onEvent(debuggeeId, method, params) {
var tabId = debuggeeId.tabId;
if (method == "Debugger.paused") {
attachedTabs[tabId] = "paused";
var frameId = params.callFrames[0].callFrameId;
chrome.browserAction.setIcon({
tabId: tabId,
path: "debuggerContinue.png"
});
chrome.browserAction.setTitle({
tabId: tabId,
title: "Resume JavaScript"
});
chrome.debugger.sendCommand(debuggeeId, "Debugger.setVariableValue", {
scopeNumber: 0,
variableName: "changeMe",
newValue: {
value: 'hijacked by Extension'
},
callFrameId: frameId
});
}
}
function onDetach(debuggeeId) {
var tabId = debuggeeId.tabId;
delete attachedTabs[tabId];
chrome.browserAction.setIcon({
tabId: tabId,
path: "debuggerPause.png"
});
chrome.browserAction.setTitle({
tabId: tabId,
title: "Pause JavaScript"
});
}
demo

EDIT: Just saw your comment about this being for a custom extension you're writing. My answer won't help you (sorry!), but it might help people that come here looking for a way of setting normal breakpoints in Chrome.
Maybe you already did, but... Have you tried just clicking the line number of the line you want to set the breakpoint in?
Like this:
You can even enable or disable breakpoints in several different calls in the same line.
When the page is loaded, open Dev Tools with F12, then navigate to the JS file in the Sources panel, and add the breakpoints you want. Then, refresh the page to load it again -- Chrome will remember where you set the breakpoints and stop at them.

If you can modify the source code of the file that you want to debug, I would look use the debugger statement.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
function potentiallyBuggyCode() {
debugger; //application will break here as long as chrome developer tools are open
}

function breakhere() {
debugger;
}

ok, for start you have to sendCommand Debugger.enable .. something like this:
var tabId = parseInt(window.location.search.substring(1));
window.addEventListener("load", function() {
chrome.debugger.sendCommand({tabId:tabId}, "Debugger.enable");
chrome.debugger.attach( tabId, "0.1" );
chrome.debugger.onEvent.addListener(onEvent);
});
then inside you onEvent you can set breaking points
function onEvent(debuggeeId, message, params) {
if (tabId != debuggeeId.tabId) return;
var res = Debugger.setBreakpointByUrl( 2, 'url-of-the-script-file' );
}
I would strongly suggest to check the sniffing section on this page: https://chromedevtools.github.io/devtools-protocol/ because I was able to see the json that get returned via WS protocol and that will help you to do pretty much anything you want.. I can't build you full extension, you are on your own man,,
I guess that you need to add somekind of DOM elemnet with list of scripts that you'll parse from Network.getResponseBody and then somekind of UX tool to pick that scripts and let users to debugging,, that process could take you some time :(
hope I have steered you in the right direction, good luck!

Related

JavaScript dialogs alert(), confirm() and prompt() in cross origin iframe does not work any longer

Apps script web app works in <iframe>. It seems Chrome is no longer supporting alert(), confirm(), Promote these functions on the web app.
Any workaround to this?
Chrome Version 92.0.4515.107 (Official Build) (64-bit) -- does not work
Edge Version 91.0.864.71 (Official build) (64-bit) -- works
Tried replacing alert() with window.alert(), but still does not work.
exec:1 A different origin subframe tried to create a JavaScript dialog. This is no longer allowed and was blocked. See https://www.chromestatus.com/feature/5148698084376576 for more details.
This is absurd and subjective decision of Google to remove alert(), confirm(), and prompt() for cross origin iframes. And they called it "feature". And justification is very poor - see "motivation" bellow. A very weak reason for removing such an important feature! Community and developers should protest!
Problem
https://www.chromestatus.com/feature/5148698084376576
Feature: Remove alert(), confirm(), and prompt for cross origin iframes
Chrome allows iframes to trigger Javascript dialogs, it shows “ says ...” when the iframe is the same origin as the top frame, and “An embedded page on this page says...” when the iframe is cross-origin. The current UX is confusing, and has previously led to spoofs where sites pretend the message comes from Chrome or a different website. Removing support for cross origin iframes’ ability to trigger the UI will prevent this kind of spoofing, and unblock further UI simplifications.
Motivation
The current UI for JS dialogs (in general, not just for the cross-origin subframe case) is confusing, because the message looks like the browser’s own UI. This has led to spoofs (particularly with window.prompt) where sites pretend that a particular message is coming from Chrome (e.g. 1,2,3). Chrome mitigates these spoofs by prefacing the message with “ says...”. However, when these alerts are coming from a cross-origin iframe, the UI is even more confusing because Chrome tries to explain the dialog is not coming from the browser itself or the top level page. Given the low usage of cross-origin iframe JS dialogs, the fact that when JS dialogs are used they are generally not required for the site’s primary functionality, and the difficulty in explaining reliably where the dialog is coming from, we propose removing JS dialogs for cross-origin iframes. This will also unblock our ability to further simplify the dialog by removing the hostname indication and making the dialog more obviously a part of the page (and not the browser) by moving it to the center of the content area. These changes are blocked on removing cross-origin support for JS dialogs, since otherwise these subframes could pretend their dialog is coming from the parent page.
Solution
Send message via Window.postMessage() from iframe to parent and show dialog via parent page. It is very elegant hack and shame on Google because before Chrome version 92 client saw alert dialog e.g. An embedded page iframe.com" says: ... (which was correct - client see real domain which invoked alert) but now with postMessage solution client will see a lie e.g. The page example.com" says: ... but alert was not invoked by example.com. Stupid google decision caused them to achieve the opposite effect - client will be much more confused now. Google's decision was hasty and they didn't think about the consequences. In case of prompt() and confirm() it is a little bit tricky via Window.postMessage() because we need to send result from top back to iframe.
What Google will do next? Disable Window.postMessage()? Déjà vu. We are back in Internet Explorer era... developers waste time by doing stupid hacks.
TL;DR: Demo
https://domain-a.netlify.app/parent.html
Code
With code bellow you can use overridden native alert(), confirm() and prompt() in cross origin iframe with minimum code change. There is no change for alert() usage. I case of confirm() and prompt() just add "await" keyword before it or feel free to use callback way in case you can not switch easily your sync functions to async functions. See all usage examples in iframe.html bellow.
Everything bad comes with something good - now I gained with this solution an advantage that iframe domain is not revealed (domain from address bar is now used in dialogs).
https://example-a.com/parent.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Parent (domain A)</title>
<script type="text/javascript" src="dialogs.js"></script>
</head>
<body>
<h1>Parent (domain A)</h1>
<iframe src="https://example-b.com/iframe.html">
</body>
</html>
https://example-b.com/iframe.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Iframe (domain B)</title>
<script type="text/javascript" src="dialogs.js"></script>
</head>
<body>
<h1>Iframe (domain B)</h1>
<script type="text/javascript">
alert('alert() forwarded from iframe.html');
confirm('confirm() forwarded from iframe.html via callback', (result) => {
console.log('confirm() result via callback: ', result);
});
prompt('prompt() forwarded from iframe.html via callback', null, (result) => {
console.log('prompt() result via callback: ', result);
});
(async () => {
var result1 = await confirm('confirm() forwarded from iframe.html via promise');
console.log('confirm() result via promise: ', result1);
var result2 = await prompt('prompt() forwarded from iframe.html via promise');
console.log('prompt() result via promise: ', result2);
})();
</script>
</body>
</html>
dialogs.js
(function() {
var id = 1,
store = {},
isIframe = (window === window.parent || window.opener) ? false : true;
// Send message
var sendMessage = function(windowToSend, data) {
windowToSend.postMessage(JSON.stringify(data), '*');
};
// Helper for overridden confirm() and prompt()
var processInteractiveDialog = function(data, callback) {
sendMessage(parent, data);
if (callback)
store[data.id] = callback;
else
return new Promise(resolve => { store[data.id] = resolve; })
};
// Override native dialog functions
if (isIframe) {
// alert()
window.alert = function(message) {
var data = { event : 'dialog', type : 'alert', message : message };
sendMessage(parent, data);
};
// confirm()
window.confirm = function(message, callback) {
var data = { event : 'dialog', type : 'confirm', id : id++, message : message };
return processInteractiveDialog(data, callback);
};
// prompt()
window.prompt = function(message, value, callback) {
var data = { event : 'dialog', type : 'prompt', id : id++, message : message, value : value || '' };
return processInteractiveDialog(data, callback);
};
}
// Listen to messages
window.addEventListener('message', function(event) {
try {
var data = JSON.parse(event.data);
}
catch (error) {
return;
}
if (!data || typeof data != 'object')
return;
if (data.event != 'dialog' || !data.type)
return;
// Initial message from iframe to parent
if (!isIframe) {
// alert()
if (data.type == 'alert')
alert(data.message)
// confirm()
else if (data.type == 'confirm') {
var data = { event : 'dialog', type : 'confirm', id : data.id, result : confirm(data.message) };
sendMessage(event.source, data);
}
// prompt()
else if (data.type == 'prompt') {
var data = { event : 'dialog', type : 'prompt', id : data.id, result : prompt(data.message, data.value) };
sendMessage(event.source, data);
}
}
// Response message from parent to iframe
else {
// confirm()
if (data.type == 'confirm') {
store[data.id](data.result);
delete store[data.id];
}
// prompt()
else if (data.type == 'prompt') {
store[data.id](data.result);
delete store[data.id];
}
}
}, false);
})();
File a feature request:
Consider filing a feature request using this Issue Tracker template.
I'd either request that an exception is made for Apps Script web apps, or that built-in methods for alert and confirm are added, similar to the existing alert and prompt dialogs, which currently work on Google editors.
Bug filed:
By the way, this behavior has been reported in Issue Tracker (as a bug):
Javascript in html files doesn't work
I'd consider starring it in order to keep track of it.
Workaround:
In the meanwhile, as others said, consider downgrading or changing the browser, or executing it with the following command line flag:
--disable-features="SuppressDifferentOriginSubframeJSDialogs"
Related question:
Chrome SuppressDifferentOriginSubframeJSDialogs setting override using JS?
So far, the only 'solution' for this is to add the following to your Chrome/Edge browser shortcut:
--disable-features="SuppressDifferentOriginSubframeJSDialogs"
Or downgrade your browser. Obviously neither of these are ideal. Google trying really hard to save us from ourselves here.

Open new tab from Chrome Extension Context Menu

UPDATE:
So because of the way my folder is structured, it looks like instead of chrome-extension://meajimhgfmioppbkoppphhkbcmapfngh/index.html it should be chrome-extension://meajimhgfmioppbkoppphhkbcmapfngh/html/index.html. When I type this in manually into the search bar it works but is still not working when I update my code to this:
chrome.contextMenus.onClicked.addListener(function (result) {
if (result['menuItemId'] === 'open-sesame') {
chrome.tabs.create({ 'url': chrome.extension.getURL("/html/index.html") }, function (tab) {
})
}
})
I have a chrome extension where users are presented my extension as a new tab. A new feature I am implementing is the ability to switch back to the default google search page and now users can access the extension from the browser action context menu. I referenced this answer when trying to come up with a solution.
I am now stuck at the contextMenu since when I click on it, I come up to the page where it says file could not be accessed.
background.js
chrome.contextMenus.create({
title: "Open",
contexts: ['browser_action'],
id: 'open-sesame',
})
chrome.contextMenus.onClicked.addListener(function (result) {
if (result['menuItemId'] === 'open-sesame') {
chrome.tabs.create({ 'url': chrome.extension.getURL("index.html") }, function (tab) {
})
}
})
The url that the new tab opens to is chrome-extension://meajimhgfmioppbkoppphhkbcmapfngh/index.html which seems like it would be correct to open my extension but it is still not working for whatever reason.
Folder Structure
html
index.html
js
background.js
css
style.css
Turns out I had to add the right file pathing to access my index.html and update the extension to get it to work.

Firefox extension: Open window and write dynamic content

I have developed a Chrome Extension and it's mostly compatible to firefox web-extensions API. Just one problem:
In Chrome Extension i have popup.js and background.js. User click's a button, popup.js does chrome.sendMessage to background.js where data is received and afterwards (popup.html may be closed meanwhile) i just call in background.js:
newWin = window.open("about:blank", "Document Query", "width=800,height=500");
newWin.document.open();
newWin.document.write('<html><body><pre>' + documentJson + '</pre></body></html>');
// newWin.document.close();
so that works fine in Chrome extension but not in firefox. I read here (https://javascript.info/popup-windows) that for safety reasons firefox will only open with a "button click event". And if i move above code to popup.js, inside button-click-evenListener, it will open this way (but i dont have the data prepared yet, thats really not what i want)
So i tried everything i found but i dont get the chrome.tabs.executeScript running. Here is my code with comments:
popup.js
// working in firefox and chrome (popup.js)
const newWin = window.open("about:blank", "hello", "width=200,height=200");
newWin.document.write("Hello, world!");
// not working firefox: id's match, he enters function (newWindow) but document.write doing nothing (but no error in log)
// not working chrome: doesnt even enter "function (newWindow)""
chrome.windows.create({
type: 'popup',
url: "output.html"
}, function (newWindow) {
console.log(newWindow);
console.log(newWindow.id);
chrome.tabs.executeScript(newWindow.tabs[0].id, {
code: 'document.write("hello world");'
});
});
background.js
(created local output.html and gave several permissions in Manifest.json - tabs, activeTab, output.html, , about:blank)
// opening but executeScript not working in firefox: Unchecked lastError value: Error: The operation is insecure.
// opening but executeScript not working in chrome: Unchecked runtime.lastError: Cannot access contents of url "chrome-extension://plhphckppghaijagdmghdnjpilpdidkh/output.html". Extension manifest must request permission to access this host
chrome.tabs.create({
// type: 'popup',
url: "output.html"
}, function (newWindow) {
console.log(newWindow);
console.log(newWindow.id);
chrome.tabs.executeScript(newWindow.id, {
code: 'document.write("hello world");'
});
});
How can I get the data into the new window/popup from background.js - i can open an empty page from there, so it's only about getting executeScript() running
Thanks to #wOxxOm for pointing me to a data URI to transport the json document into the browser from background.js.
While searching for a javascript method to build a data URI i found this thread, with the suggestion to create a Blob :
https://stackoverflow.com/a/57243399/13292573
So my solution is this:
background.js
var documentJson = JSON.stringify(documents, null, 2)
let a = URL.createObjectURL(new Blob([documentJson]))
chrome.windows.create({
type: 'popup',
url: a
});

Chrome Extension error: "Unchecked runtime.lastError while running browserAction.setIcon: No tab with id"

I'm coding my Google Chrome Extension where I set the app's icon from the background script as such:
try
{
objIcon = {
"19": "images/icon19.png",
"38": "images/icon38.png"
};
chrome.browserAction.setIcon({
path: objIcon,
tabId: nTabID
});
}
catch(e)
{
}
Note that I wrapped the call in try/catch block.
Still, sometimes I'm getting the following message in the console log:
Unchecked runtime.lastError while running browserAction.setIcon: No
tab with id: 11618.
It's hard to debug this error because it seems to come up only when I close or reload the Chrome tab, it doesn't have a line number or any info for me to track, plus it's not easy to run through a debugger (i.e. I cannot set a break-point on the moment when error occurs, but if I blindly set a break-point on the chrome.browserAction.setIcon() line, I don't see the message in the log anymore.)
So I'm curious if anyone could suggest how to remedy this error?
EDIT: Just to post an update. I am still unable to resolve this issue. The suggestion proposed by #abraham below offers a somewhat working approach, but it is not fail safe. For instance, in a situation when the tab is closing I may call his suggested chrome.browserAction.setIcon() that may succeed if the tab is not yet closed, but while within its callback function the tab may eventually close and thus any consecutive calls to some other API that requires that same tab ID, say setBadgeBackgroundColor() may still give me that same No tab with id exception. In other words, for those who know native programming, this is a classic race condition situation. And I'm not sure if it's a bug in Chrome, because obviously JS does not offer any thread synchronization methods...
I've witnessed this behavior several times while doing my tests. It doesn't happen often because we're talking about very precise timing situation, but it does happen. So if anyone finds a solution, please post it below.
Include a callback and check chrome.runtime.lastError.
objIcon = {
"19": "images/icon19.png",
"38": "images/icon38.png"
};
function callback() {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
} else {
// Tab exists
}
}
chrome.browserAction.setIcon({
path: objIcon,
tabId: nTabID
}, callback);
The below works for me
/**
* Update icon, text and background
* Handle the case where the tab_id no longer exists
*/
function updateIconAndBadge(tab_id, icon_path, badge_text, badge_background_color) {
// Set the icon path
chrome.browserAction.setIcon({ path: icon_path, tabId: tab_id },
// Call back
() => {
// Check for error
if (chrome.runtime.lastError) {
// Failed - tab is gone
console.log(`Tab ${tab_id} no longer exists.`);
}
else {
// Ok - Set the badge text
chrome.browserAction.setBadgeText({
tabId: tab_id,
text: badge_text
});
// Set the back ground colour
chrome.browserAction.setBadgeBackgroundColor({
tabId: tab_id,
color: badge_background_color
});
}
});
}

Checking if user has a certain extension installed

I just found out that the Screen Capture by Google extension makes my website's window.onresize event not fire.
I want to perform a javascript check to see if the user has ScreenCapture installed and if so, warn the user of the problem.
A year ago I think I heard of some javascript code that could do this, maybe using some google API, but I don't remember.
Any insight on this? I haven't developed any extensions so I don't really know how they work.
[EDIT]
So I have been asked to show some code. As seen in my previous question ( window.onresize not firing in Chrome but firing in Chrome Incognito ), the problem occurs on any window.onresize event function, so I don't think my code really matters.
Also, there is quite a lot of my code, I don't know how much of it to paste or if it would be helpful.
var debounce = function (func, threshold, execAsap)
{
var timeout;
return function debounced () {//alert("1.1 Y U NO WORK?");
var obj = this, args = arguments;
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
}
if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
};
};
window.onresize = debounce(function (e) { //alert("1.2 Y U NO WORK?");
flag = true;
var point = window.center({width:1,height:1});
doCenter(point);
// does something here, but only once after mouse cursor stops
}, 100, false);
I would like to stress that the problem is not due to the debounce. window.onresize = t; function t (e) { alert("wtf?");} won't work either.
[EDIT2]
Here's the result:
var screenCapture = null;
var screenCaptureImg = document.createElement("img");
screenCaptureImg.setAttribute("src", "chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/images/arrow.png");
/*
* Add event listeners for both "load"- and "error"-event
* Set the variable showing the existence of the extension by
* setting it to "true" or "false" according to the fired event
*/
screenCaptureImg.addEventListener("load", doLoad, false);
function doLoad(e){
screenCapture = true; //removeImgTag(e);
alert("I've so cleverly detected that your Chrome has the ScreenCapture extension enabled. \n\nThis extension interferes with my website's DOM and long story short, it won't be able to scale properly.\n\nSo please disable it. \nConsider this extension: \"Disable All Extensions Plus\", it's a handy selective disabler.");
}
screenCaptureImg.addEventListener("error", function(e){
screenCapture = false; //removeImgTag(e);
}, false);
/*
function removeImgTag(e) {
e.currentTarget.parentNode.removeChild(e.currentTarget);
}
*/
Note that I couldn't get removeImgTag to work, because (at least in chrome), I don't seem to have access to the document object in order to create or remove elements from my page, from within these event functions. This is also why I'm displaying an alert instead of elegantly writing up a document.getElementById("something").innerHTML=...
To detect if an extension is installed in Chrome, you can check for a known resource included in the extension such as an image. Resources for the extension are referenced using the following URL pattern:
chrome-extension://<extensionID>/<pathToFile>
The basic detection technique involves creating a hidden image tag and attaching load and error events to it to see if the image loads (as described here for Firefox):
extensionImg.setAttribute("src", "chrome-extension://<INSERT EXTENSION ID HERE>/images/someImage.png"); // See below for discussion of how to find this
/*
* Add event listeners for both "load"- and "error"-event
* Set the variable showing the existence of the extension by
* setting it to "true" or "false" according to the fired event
*/
extensionImg.addEventListener("load", function(e) {
extensionExists = true;
removeImgTag(e);
}, false);
extensionImg.addEventListener("error", function(e) {
extensionExists = false;
removeImgTag(e);
}, false);
function removeImgTag(e) {
e.currentTarget.parentNode.removeChild(e.currentTarget);
}
Check the installation directory of the extension in the Chrome configuration to find a likely target for detection. On my Linux workstation extensions are located in:
~/.config/chromium/Default/Extensions
You can see that I have 3 extensions installed right now:
~/.config/chromium/Default/Extensions$ ls
cpecbmjeidppdiampimghndkikcmoadk nmpeeekfhbmikbdhlpjbfmnpgcbeggic
cpngackimfmofbokmjmljamhdncknpmg
The odd looking names are the unique IDs given to the extension when it is uploaded to the Chrome webstore. You can obtain the ID either from the webstore or by going to the Extensions tab (wrench -> Extensions) and hovering over the link to the extension in question, or "Screen Capture (by Google)" in this case (note the asterisked extension ID):
https://chrome.google.com/webstore/detail/**cpngackimfmofbokmjmljamhdncknpmg**
In the extension directory there will be one or more versions; you can ignore this. Within the version directory is the actual content of the extension:
~/.config/chromium/Default/Extensions/cpngackimfmofbokmjmljamhdncknpmg/5.0.3_0$ ls
account.js images page.js sina_microblog.js
ajax.js isLoad.js picasa.js site.js
background.html _locales plugin style.css
editor.js manifest.json popup.html ui.js
facebook.js notification.html sha1.js upload_ui.js
hotkey_storage.js oauth.js shortcut.js
hub.html options.html showimage.css
i18n_styles page_context.js showimage.html
In the case of the Screen Capture extension there are a number of images to use:
~/.config/chromium/Default/Extensions/cpngackimfmofbokmjmljamhdncknpmg/5.0.3_0/images$ ls
arrow.png icon_128.png icon_save.png print.png
copy.png icon_16.png line.png region.png
cross.png icon_19.png loading.gif screen.png
custom.png icon_32.png loading_icon.gif sina_icon.png
delete_account_icon.png icon_48.png mark.png toolbar_bg.png
down_arrow.png icon_close.png picasa_icon.png upload.png
facebook_icon.png icon_copy.png popup_bg.jpg whole.png
These can be referenced under this URL:
chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/images/arrow.png
This technique obviously depends on the stability of the content of the extension. I recommend using an image that looks likely to remain through all versions.
As mentioned above, the same technique can be used to detect Firefox extensions. In this case the content URL looks like this:
chrome://<EXTENSION NAME>/content/<PATH TO RESOURCE>
On my Linux workstation Firefox extensions are located in:
~/.mozilla/firefox/<USER PROFILE ID>/extensions
Where <USER PROFILE ID> looks something like this: "h4aqaewq.default"
You can see that I have 2 extensions installed right now, one of which is a directory installation and the other of which is a XPI (pronounced "zippy") file:
~/.mozilla/firefox/h4aqaewq.default/extensions$ ls
{3e9a3920-1b27-11da-8cd6-0800200c9a66} staged
firebug#software.joehewitt.com.xpi
The "staged" directory is where Firefox keeps extensions that will be updated (I think). The GUID directory with the brackets is a directory-based extension installation, and the .xpi file is Firebug.
Note: XPI is going away (see the link above). It's basically a zip file that can be opened and inspected by anything that understands zip. I used Emacs.
Finding the extension ID in Firefox is a bit more involved. Go to "Tools -> Add-ons", click the Extensions tab, click the "More" link next to the extension description, then click the "reviews" link to go to the Firefox extension site and get the ID from the URL (note the asterisked extension ID):
https://addons.mozilla.org/en-US/firefox/addon/**firebug**/reviews/?src=api
There's probably an easier way to do this; suggestions welcome.
TODO: how to find a likely image in a Firefox extension.
As an extra note, in Chrome you can only communicate with an extension via the shared DOM of the page: Host page communication

Categories

Resources