Save last session of chrome extension - javascript

In my html file I have a simple table and a couple of buttons that allow adding/removing rows. If I store that html in popup.html, then every time I close chrome extension the session disappears. That is if I added some rows and put some values to the cells of that table, once I go from my extension, these rows and values disappear when I click on the extension again.
As a solution I saw putting that html to background.html and retrieving that code from popup.js:
// listeners to save/restore document.body
window.addEventListener("unload", function(event) {
chrome.extension.getBackgroundPage().docBody = document.body;
});
window.addEventListener("load", function(event) {
var
docBody = document.body,
lastDocBody = bgPage.docBody;
if (lastDocBody)
docBody.parentElement.replaceChild(document.importNode(lastDocBody,true),
docBody);
});
However, it doesn't output any content of background.html to my extension.
The question is general: I would like to save the last state of my table, no matter if I closed the extension or not. How can I do this?
Or in particular, how can I load/save page from/to background.html and upload its content to popup.js

You will have to use one of the storage APIs provided.
Best one to use is chrome.storage, but you can also use localStorage inside chrome extension pages. See this question for a comparison. You don't need background page for either.
Do note: you cannot store DOM nodes directly in such storage, since the data has to be JSON-serializable, and DOM nodes contain circular references.
So you'll need to store data used to add your rows instead of the rows themselves, and add them again when restoring state. It is a good idea anyway to store "raw" data.

Related

Specification for Saving a Webpage

Is there a specification for what happens when a webpage is saved?
I would like to create an html application for editing documents and would like the browser's built-in save/load functions to allow the user to save their work partially through editing, so they can load the web page and continue working.
I'm aware of how to save/load files within javascript itself using objectURLs and file selection inputs, but this seems more elegant.
My current approach is to take all of the important data and store it in a hidden, originally empty, div within the body of the webpage, since this seems to stick around when I save a webpage. My page's onload then searches to see if this hidden div contains useful data (in which case a saved version of the page is being loaded) and puts it into the appropriate variables and textareas.
However, I am unable to determine if this is correct across all specification-compliant browsers: a browser might decide not to save the content of invisible divs.
Testing with Chrome (109), it looks like:
The contents of textareas modified in code are saved
The contents of textareas modified manually are not saved
The contents of input type="text" is not saved in either case
the contents of divs modified or created in code are saved
Testing with Firefox (109), it looks like:
The contents of textareas modified in code are saved
The contents of textareas modified manually are saved
The contents of input type="text" is saved in either case
the contents of divs modified or created in code are saved

How can I get a div that exists in the website's source code but not exists in the document?

I want to make a Chrome extension to classify the people who I am following in the website www.zhihu.com, because this website don't have this function.
when I view the source code of the website, I find my personal data is put in a div that whose id is named data.
So I want to obtain this div. But, when I log this div in the document, it becomes null.
Why does this happen? And how can I get a div that exists in the website's source code but not exists in the document?
It could be several reason: first of all, the view source is not a live representation of the document, it's the source the server has sent to the client. It means, it might be no longer valid. Try to load this in the address bar (of a modern browser, possibly):
data:text,<div>hello</div><script>document.querySelector("div").remove()</script>
And check the view source. The source will contains the div, but if you use the inspector from devtools you will see that the div no longer exists (of course, we removed that by JS).
Another scenario, could be that you're logging from a different frame context: if the web pages contains frames, you might be in a frame context where your div is not present.

How can I embed hidden data in a web page and recover it using the DOM?

I have a web page that draws data from several other local (same origin) web pages. I collect the data from these other web pages using XMLHttpRequest. I then use the DOM to parse out the needed data from each page. There is one piece of data that I would like to include in each of the other local pages (i.e., in the DOM for each of the other local pages), however, I don't want that data visible when the web page is viewed. (Visible in the source code is OK, just not in the rendered HTML). I can think of a couple of ways of doing that. However, I am not enammered with any of them. I'm wondering what suggestions others might have. Thanks for any input.
Some options:
The hidden attribute:
All HTML elements may have the hidden content attribute
set. The hidden attribute is a boolean attribute. When
specified on an element, it indicates that the element is not yet, or
is no longer, directly relevant to the page's current state, or that
it is being used to declare content to be reused by other parts of the
page as opposed to being directly accessed by the user. User agents
should not render elements that have the hidden attribute
specified.
The template element
The template element is used to declare fragments of HTML that
can be cloned and inserted in the document by script.
In a rendering, the template element represents nothing.
Comments
Depending on the semantics, you can choose one or another. Or even combine them:
<template hidden><!-- Hidden data --></template>
As you mentioned to get through AJAX request, it is in your control where to show or not.
Once you get the result through AJAX, you can store in your script to do some manipulation or show in HTML page itself with parent tag as visible false, so that end user cannot see (except Source code viewing).
What's wrong with a simple hidden div?
<div id="hiddenData" style="display:none;">...</div>
To be honest, it seems like the way you are passing around data is kind of a hack already, so I don't see any real need to be fancy.

How to read current page's HTML to access an element from a Chrome extension?

I'm working on my first chrome extension. My extension works on specific pages.
I need to access the current page of the user, and get values from the 'table' element in the page.
Do I need contentscript page or is background.html enough? How do I access the table element then?
Read this SO question in order to understand the difference between content script and background script. Now, back to your question
Since you want to get access to the DOM element of the current page, you need to do the following:-
In your manifest.json, make sure you have the url pattern which matches the current page url.
Make your your content script runs after page load on the current page
Once you ensure 1 and 2, you can use simple query selectors to get access to the table element and get the values you need.
Now it depends what you do want to do with the table values you have obtained. If you need them in the background script for storage purpose or some other purpose, you can use Mesage Passing to send the values to background script.

Modifying Google Search Results Page

I have written a greasemonkey script which will do GM_xmlhttpRequest
to the next 2 pages of the google results page.. i.e. if my current
page is 1 then my script will do GM_xmlhttpRequest to page no 2 and
3..
Now my script will extract out all the urls from these 3 pages and
will reorder them
For that I have done:
unsafeWindow.addEventListener('load',Reorder,true);
function Reorder()
{
alert("onload fired")
..........
..........
// some code overhere to collect all the urls into an array
// and to reorder the urls in the array
Now I inject these urls into my reference pages i.e. I keep a
reference to the nodes where I am supposed to append these urls as
childNodes.. and along with that I modify the links to page no. 2 and
3(at the bottom of results page) so that now they'll point to my these newly dynamically generated
pages. For that I modify the onclick attribute of these links that'll
open a new window in the current window itself and will write the
modified responseXML object to the newly created window.
Now everything is working awesome i.e. url
extraction, reordering, creating new window, writing the responseXML
object ..
But the problem is that when my these modified links are clicked and
my newly generated window replaces the parent window it doesn't give the alert of "onload fired"
...infact it doesn't stop loading i.e. it displays the desired
content but is never fully loaded since status bar doesn't shows
"done" in fact it shows "waiting for clients1.google.com"...
So does anyone knows what exactly is going wrong over here.. is it due
to some script running on google search page that is somehow
synchronised with the contents of the page...
Basically for those who do not know how greasemonkey will work.....my code is just removing all the anchor tags that contain url and inserting similar anchor tags with different urls...the question in nutshell is that i am just making a new window and doing document.write(this newly created html page)...and other than the urls I am not changing anything....
so basically are the scripts somehow synchronized with the urls present on the page or does it really matter to the scripts what data is contained within as long as the body contains the same DOM tree.
Please people whatever you know or have idea about it.. please tell me...
i need to finish this thing quickly..
When you use document.write to write content into a new page, you need to use document.close() to tell the browser that you're done - until then, the browser thinks there is more content to come and continues to display the loading icon.

Categories

Resources