Changing chrome extension html using chrome storage event listener - google-chrome

With this code I want to create an event listener for whenever chrome storage updates.
I want 2 things to happen when the event listener is triggered:
The code will console log the updated values. This part works.
I want the HTML for the extension (the document that opens in the corner when you click the icon) to update and render the data value that is in chrome storage. This is that part I need help with.
chrome.storage.onChanged.addListener(function(changes, namespace) {
//part 1
console.log('New data type is %s. New value is %s',
changes['type'].newValue, changes['data'].newValue)
//part 2
document.getElementById('output').innerHTML =
changes['data'].newValue
});
I realize that calling "document" inside the function doesn't make sense, but I'm unsure how to move forward to get it to render in the extension's HTML.
I tried creating an event listener for when the context menu is accessed (users can update the chrome storage but clicking a button in the context menu) but I couldn't get it to work. Also the event should trigger when chrome storage is updated, not when the context menu is simply accessed.
Right now I get this error:
Error in event handler: TypeError: Cannot set property 'innerHTML' of null
(There is an element with id 'output', so that isn't the problem)
Thanks for your help!

The background script runs in a separate hidden background page. It's not related to the browserAction or pageAction popup page, it doesn't have any of the popup page elements, its DOM is empty except for the auto-generated script tags of the background scripts.
The popup is also a separate page and just like any normal page its environment/DOM exists only when the page is shown. You can't modify it when it's not shown. You can't show it from your code in general case either.
Solution 1
Put that onChanged listener in popup.js script that's loaded in your popup.html (declared as "browser_action": {"default_popup":"popup.html"} in your manifest.json) using the standard <script src="popup.js"></script> tag. It will update the popup page if it's shown, and to display the current values when the popup opens read them with chrome.storage.local.get or chrome.storage.sync.get depending on which storage you're using in your extension.
Solution 2
Use chrome.notifications API to show a small notification at the bottom of the screen, see also the official demo extensions.
Solution 3
Use chrome.browserAction.setBadgeText to display short text like a temperature right under the extension icon. Don't forget to declare at least "browser_action": {} in your manifest.json.

Related

Chrome Extension Manifest V3 Screen Recording Ends When Changing the Tab

I am trying to migrate my extension which records screen/tab/window according to the chosen option from manifest V2 to V3. In manifest V2 I was able to use background script as persistent and reach html page objects such as mediaRecorder, navigator. However in manifest V3 background script works as a service worker. So, I have to start the screen record in content-scripts to be able to reach the html objects. When I start chrome.desktopCapture API from the background script, I have to start the screenRecord in one of the tabs (should give a tabid to chrome.desktopCapture.chooseDesktopMedia API call). I cannot start it on the background page and when the page was refreshed or changed to a new URL screen record stops. Is there any workaround for this?
I believe the best way to handle updates such as a URL change on a tab is to attach the onUpdated listener to the chrome tabs in the background script.
chrome.tabs.onUpdated.addListener(function(tabId, changes, tab) {
//Detect Type of Change and Handle Accordingly
});
There are quite a few other events that may be of use that are listed in the chrome documentation Chrome Tabs Events. It's also possible to inject inline JavaScript from the content script so you can access the pages window object directly and attach event listeners there to handle reloads or URL changes. Check this stack overflow post for more information Modify Window Object in Chrome Extension

How to show the upload file dialog on page load

Using PF10 (in a JoinFaces project), I'd like the Upload File dialog for choosing a file to show up when the page loads (i.e., without waiting for the user to click on the Choose button of <p:fileUpload/>). How can I do that?
You could use client side API show() function for this. But it seems more and more browsers are blocking triggering a click by script on an input type="file". See https://github.com/primefaces/primefaces/issues/7772
You could take your chances and try to hijack a mouse move event to trigger a click on the upload input, which is answered on this question: In JavaScript can I make a "click" event fire programmatically for a file input element? But I don't really like that hack.

Looking for an info on the chrome's debugger

I am trying to understand how to get from the chrome debugger the following info : there is an event on page triggered by a click on an input file type tag. But it is impossible for me to trace back the mecanism : which js file is called when the event is triggered. Is there a way do get this info from the debugger ?
Do you have a look at the Event Listeners entry in the right-hand window? If I right-click the 'Google-Chrome' tag at the bottom of your post, and select Inspect Element, I get the html tag highlighted. If I then look in the right-hand pane at the Event Listeners, I can see that this element has handlers for blur, click, keyup, keydown, mousedown, mouseout, mouseover. Yet just looking at the html I can't see that. If I expand the event handlers, I can see that they all point to "jquery.min.js : 3". This is because the file has been minimized and is only 4 lines - each of which is probably 20 or 25,000 chars long. Minimized scripts are difficult to analyse unfortunately.
Try it with a page that doesn't use minimizes scripts and you can click the link in the event handler window to be taken directly to the pertinant function - unfortunately, you are taken to the start of the line concerned, which makes jquery.min.js a waste of time to do this with. You can always use the non-minified version of a script for debugging purposes, switching over to the minified version for production.
With other's pages, you can sometimes get away with saving a local copy, before linking an unminified version of the script.

Chrome extension that runs in the background on window open event?

How can I make a Chrome extensions that is not a popup or a button?
I wanna have a script running whenever the window is opened and iterate thru all its tabs performing actions on each tab.
I also need (is this possible?) want to add to the same extension buttons (+keyboard shortcuts?) that when clicked, perform actions on all tabs.
Then I need control on these buttons visibility, and make them visible only in certain conditions (e.g. show only when page is loading, hide when not-loading).
Where do I put my script and how do I refer to it in my *.json manifest?
Any info/links will be appreciated.
The answers to 0 and 1 can directly be found in the documentation, specifically background pages, chrome.windows API and chrome.tabs API.
To bind global events, use the chrome.experimental.keybinding API. Because this API is experimental, you have to enable it first at chrome://flags. Also, the extension cannot be uploaded to the Chrome Web store.
If you want to add an "extension button" which performs some action on click, define a browser action and bind an event listener to chrome.browserAction.onClicked.
To select all tabs, use chrome.tabs.query({}, callback) method ({} means no filter, so all tabs are selected).
Browser action buttons are always visible. If you want to create a button which is not always visible, use a page action instead. The chrome.tabs module includes several events which can be used to find out whether your conditions are met.
As for putting up the script and the manifest file, read the documentation on Manifest files and explore some examples.

How to get the changed content in the page?

I wrote a user script for the latest Chrome browser. It seems the script can't get the changed content of the page after loaded (for example, after the page loaded, I clicked ¿sth? and an embedded window popped up).
Even if I used window.setTimeout(), I still can't the get updated content in the timer callback through document.getElementById(). I inspected the page and found that the popup element existed in the DOM.
Is this a limitation of user script? Or some other methods could be used to get the update in user script?
Update:
I tried DOMSubtreemodified event as suggested. But the behavior is still strange.
I added only one one line of JavaScript to the userscript for my.safaribooksonline.com,
document.addEventListener("DOMSubtreeModified", function () {
alert(eval('typeof OpenSignInPopup')); });
But the alert box shows "undefined" as the evaluate result of OpenSignInPopup. But I can run the alert statement in the script console in the same page at the same time, and shows the result as "function".
This function was not loaded when the user script is running at first. So how can I use it in the user script?
You need to provide details, like the relevant code snippet(s) and the pages targeted.
In general, you can fire off the DOMSubtreeModified event in chrome. That should get you access to the changed DOM.
Also, are you sure the new content is not in an iframe?
Update for new OP info:
But the alert box shows "undefined" as the evaluate result of OpenSignInPopup.
In Chrome, Greasemonkey code cannot interact with the page's JS functions like that. You'll need to inject your code into the page. See this SO answer for more information.