I'm pretty much lost on how to make the added contents of my popup window not disappear every time I open a new link or click it "away". I've read about content script, background script and the like but I don't honestly know how to implement that into my own source code. Below is my popup.html, popup.js and my manifest.js file.
{
"manifest_version": 2,
"name": "URL_save",
"description": "This extension saves an URL and renames the title to the user's wishes and hyperlink the title.",
"version": "0.1",
"browser_action": {
"default_icon": "/img/icon.png",
"default_popup": "popup.html",
"default_title": "See your saved websites!"
},
"permissions": [
"tabs"
]
}
popup html:
<html>
<head>
<title>Your articles</title>
<link href="/css/style.css" rel="stylesheet"/>
<script src="/js/underscore-min.js"></script>
<script src="/js/popup.js"></script>
</head>
<body>
<div id="div">No content yet! Click the button to add the link of the current website!</div>
<div><ul id="list"></ul></div>
<br/>
<button id="button">Add link!</button>
</body>
</html>
popup.js:
// global variables
var url;
// event listener for the button inside popup window
document.addEventListener('DOMContentLoaded', function() {
var button = document.getElementById('button');
button.addEventListener('click', function() {
addLink();
});
});
// fetch the URL of the current tab, add inside the window
function addLink() {
// store info in the the queryInfo object as per:
// https://developer.chrome.com/extensions/tabs#method-query
var queryInfo = {
currentWindow: true,
active: true
};
chrome.tabs.query(queryInfo, function(tabs) {
// tabs is an array so fetch the first (and only) object-elemnt in tab
// put URL propery of tab in another variable as per:
// https://developer.chrome.com/extensions/tabs#type-Tab
url = tabs[0].url;
// format html
var html = '<li><a href=' + url + " target='_blank'>" + url + '</a><br/></li>';
// change the text message
document.getElementById("div").innerHTML = "<h2>Saved pages</h2>";
// get to unordered list and create space for new list item
var list = document.getElementById("list");
var newcontent = document.createElement('LI');
newcontent.innerHTML = html;
// while loop to remember previous content and append the new ones
while (newcontent.firstChild) {
list.appendChild(newcontent.firstChild);
}
});
}
In this images you see what happens when I first add a link but then close (only) the popup window, opening it again:
After adding the current URL:
After closing and re-opening the popup:
Similar to a web page, the popup's (or an options/settings page's) scope is created when it is shown and destroyed when it is no longer visible. This means that there is no state stored within the popup itself between the times that it is shown. Any information which you desire to persist after the popup is destroyed, you will need to store somewhere else. Thus, you will need to use JavaScript to store any state which you desire to have be the same the next time the popup is opened. Each time the popup is opened, you will need to retrieve that information and restore it to the DOM. The two most commonly used places are a StorageAreaMDN, or the background page.
Where you store the information will depend on how long you want the data you store to persist, and where you want the data to be seen.
The general locations where you could store data include (other possibilities exist, but the followin are the most common):
chrome.storage.local
MDN if you want the data to persist on the local machine across Chrome being closed and restarted.chrome.storage.sync
MDN if you want the data shared with all instances of Chrome which use the current Chrome account/profile. The data will also persist until changed. It will be available through Chrome being closed and restarted. It will be available on other machines using the same profile.window.localStorage
: Prior to the existence of chrome.storage
it was popular to store data for the extension in window.localStorage
. While this will still work, it is generally preferred to use chrome.storage
.One of the advantages of using a chrome.storage
StorageAreaMDN is that the data is directly available to all portions of your extension without the need to pass the data as a message.1
Currently your code is not storing the URLs that are entered anywhere other than in the DOM of the popup. You will need to establish a data structure (e.g. an array) in which you store the list of URLs. This data can then be stored into one of the storage locations mentioned above.
Google's example on the Options documentation page2, MDN shows storing chrome.storage.sync
and restoring values into the DOM when the options page is displayed. The code used in this example can for the options page can work exactly as-is for a popup by just defining its HTML page as the default_popup
for a browser_action
. There are many other examples available.
Unfortunately, without more specifics from you as to what you desire, it is difficult to give you specific code. However, couple of suggestions to head in the direction you need to go are:
addUrlToDom(url)
). This function will be used when the user adds a URL and when the URLs are restored when the page loads.Store your list of URLs in an array (e.g. urlList
). This array will be what you save into the storage location outside of your popup. You will read this array from that storage location in your DOMContentLoaded
handler and use the refactored addUrlToDom()
function to add each value. Restoring it into the DOM could look something like:
urlList.forEach(function(url){
addUrlToDom(url);
});
chrome.storage.local
Assuming you want to store the URLs on the local machine across Chrome shutdown/restart (i.e. use chrome.storage.local
), you code could look something like:
manifest.json changes to permissions
only:
"permissions": [
"tabs",
"storage"
]
popup.js:
// global variables
var urlList=[];
document.addEventListener('DOMContentLoaded', function() {
getUrlListAndRestoreInDom();
// event listener for the button inside popup window
document.getElementById('button').addEventListener('click', addLink);
});
// fetch the URL of the current tab, add inside the window
function addLink() {
chrome.tabs.query({currentWindow: true,active: true}, function(tabs) {
// tabs is an array so fetch the first (and only) object-element in tab
var url = tabs[0].url;
if(urlList.indexOf(url) === -1){
//Don't add duplicates
addUrlToListAndSave(url);
addUrlToDom(url);
}
});
}
function getUrlListAndRestoreInDom(){
chrome.storage.local.get({urlList:[]},function(data){
urlList = data.urlList;
urlList.forEach(function(url){
addUrlToDom(url);
});
});
}
function addUrlToDom(url){
// change the text message
document.getElementById("div").innerHTML = "<h2>Saved pages</h2>";
//Inserting HTML text here is a bad idea, as it has potential security holes when
// including content not sourced entirely from within your extension (e.g. url).
// Inserting HTML text is fine if it is _entirely_ sourced from within your
// extension.
/*
// format HTML
var html = '<li><a href=' + url + " target='_blank'>" + url + '</a></li>';
//Add URL to DOM
document.getElementById("list").insertAdjacentHTML('beforeend',html);
*/
//Build the new DOM elements programatically instead:
var newLine = document.createElement('li');
var newLink = document.createElement('a');
newLink.textContent = url;
newLink.setAttribute('href',url);
newLink.setAttribute('target','_blank');
newLine.appendChild(newLink);
document.getElementById("list").appendChild(newLine);
}
function addUrlToListAndSave(url){
if(urlList.indexOf(url) === -1){
//URL is not already in list
urlList.push(url);
saveUrlList();
}
}
function saveUrlList(callback){
chrome.storage.local.set({urlList},function(){
if(typeof callback === 'function'){
//If there was no callback provided, don't try to call it.
callback();
}
});
}
<script>
tag into the DOM of a web page. This can be a bit complex, any you probably don't need to be concerned about it. It is mentioned here merely because there is a possible exception to the statement that the StorageAreaMDN data is available to all areas of your extension.chrome.*
, using callbacks, and browser.*
, using promises.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With