Chrome extension logic is not wοrking - javascript

I've managed to get most of my Chrome extension working, but there is a problem I can't work out.
You can grab it here if you want and load it as an unpacked extension.
After loading it works like this.
You are prompted that they need to enter a URL on the options page.
You enter a URL (e.g. http://example.com) on the options page as asked and click save, and then when you click the icon in the toolbar you can see the web page appear in the popup.
If you then go and removes the URL from the options page and clicks save, then the popup does not show the original prompt page they saw at the beginning.
I think this code (from popup.js) is at fault, but I can't see why it won't work.
var url = localStorage.url;
var alturl = chrome.extension.getURL("need-to-enter-url.html");
var element = document.getElementById("testerURL");
if (url != undefined || url != null) {
element.src = url;
} else {
element.src = alturl;
};

When you "remove" the url you are actually saving an empty string. localStorage.url = "" so your value checking is failing. I would also recommend tweaking the if logic to be clearer.
Use something like this:
if (url === undefined || url === null || url === "") {
element.src = alturl;
} else {
element.src = url;
}
Optionally you can rely on JavaScript's truthiness.
if (url) {
element.src = url;
} else {
element.src = alturl;
}

Related

Window.location.href not working inside an onmessage event?

I have an iframe, inside the iframe there is a form, the form is loaded either empty or with errors message or success message, very basic form, no AJAX or Axios, the page refreshes with the form & success or error messages
I am using this iframe inside another website, when my form is being submitted, I have to scroll to it from the window parent, if there an error message I scroll to it for example
Did not implement that completly, because this is not my problem
This a script I added inside the form ( and iframe of course )
<script>
let errors = document.getElementsByClassName("msg-error");
let data = [];
if(errors.length !== 0) {
for(let i = 0; i<errors.length; i++){
data.push(errors[i].classList[1]);
let anchor = errors[i].getElementsByClassName("error-anchor")[0];
anchor.id = (errors[i].classList[1] + "").trim();
}
}
window.onmessage = function(event) {
event.source.postMessage({message: "TESTForm", data}, event.origin);
};
</script>
I am sending a message to the hosting page! for now, if there is error message, their id are going to be sent the the hosting page
On the hosting page I have this :
<script>
// Main page:
window.onmessage = function (event) {
if (event.data.message === "TESTForm") {
let receivedData = event.data.data;
console.log("JOCELYN", receivedData.length === 0);
window.location.href = receivedData.length === 0 ? "#frmTestFrame-1" : "#" + receivedData[0];
}
};
</script>
I receive the message, how I know I am receiving them ?
console.log shows me when the page loads for the first time "JOCELYN true" as a result, & if there is an error it shows me "JOCELYN false"
But in either cases, I have to see an anchor in my url ? right ? in both cases, either true or false! But I don't see it at all, that my original url
Why ? I don't know, and that's why I am here!
Any help would be much appreciated really!

How can i run JavaScript inside my webpage only once?

So I am trying to implement an auto language changer for my webpage.
But it keeps refreshing the page as it keeps running.
I want to run this script only once so it doesn't refresh my page forever.
I have this script:
var language = navigator.language || navigator.userLanguage;
language = language.substring( 0, 2 );
if (language == "pt" || "pt-BR" || "pt-PT"){
window.location.href = "index.html";
}
else {
window.location.href = "indexEN.html"; //
}
And its called by:
<!-- Auto Language -->
<script src="js/language.js"></script>
Think about it as if you have an infinite loop, like while (true) {} — what you need to do is break out of the loop at some point. To break out of this loop, you need to add a check to make sure you're not already on the intended page. That will stop the constant redirection.
var language = navigator.language || navigator.userLanguage
language = language.substring(0, 2)
var ptPage = 'index.html'
var enPage = 'indexEN.html'
// you're calling substring, so no need to check the variants
// your check was also incorrect :)
if (language == "pt") {
if (window.location.pathname !== '/' + ptPage) {
window.location.href = ptPage
}
} else if (window.location.pathname !== '/' + enPage) {
window.location.href = enPage
}
Refreshing the page is part of your code, as you can see here
var language = navigator.language || navigator.userLanguage;// get users default language
language = language.substring( 0, 2 );
if (language == "pt" || "pt-BR" || "pt-PT"){
window.location.href = "index.html";
}
else {
window.location.href = "indexEN.html"; //loading another html file for users who use english
}
So since you are reloading another html file, your javascript IS going to run again. A solution to this would be to make your webpage a SPA (single page application). That way you wouldn't have to reload anything (including javascript). You can also change page content and headers without actually loading a new file. SPA's are usually done in react (with react routing) but you can make then vanilla JS too.
https://medium.com/altcampus/implementing-simple-spa-routing-using-vanilla-javascript-53abe399bf3c
Don't know if it is a best practice but you can use localStorage.
if((localStorage.getItem('pageLoaded') ?? 'true') === 'true') {
alert('dsds')
localStorage.setItem('pageLoaded', 'false')
}
The alert will be executed once

prepend to url of page using javascript

I need all blog product pages to show in a popup. In order to show in the popup their url must be in the form https://expample.com?/modal-link=blog_page_url. (I'm using the plugin and this is the requirement)
I would like to write a code in javascript that checks the URL. If the URL of the page contains the word 'product' I would like prepend to the url: https://expample.com?/modal-link= inorder to enable it to be shown in a popup.
I'm using the code below:
if(window.location.href.indexOf("product") > -1) {
var url = window.location.href;
url_new = 'https://example.com/?modal-link=' + url
} else {
}
window.location.href = url_new;
The is creating a new URL but it is causing it to be added an infinite amount of time.
How should I be doing this?
Follow on question: (should I open a new question for this?)
I would like to adapt the code so the page does not reload during the redirect.
I know there are other posts about this eg How do I modify the URL without reloading the page? or https://stackoverflow.com/questions/3338642/updating-address-bar-with-new-url-without-hash-or-reloading-the-pagebut could someone please help me modify my javascript code for this specific case?
Would I need to use the lines below?
document.location.hash = 'afterhash';
history.pushState('data to be passed', 'Title of the page', '/test');
I'm at a loss which part of my code need to go where in the above lines.
Your recursion is missing a stop condition. For example, if "some_product" contains "product" and you prepend anything to it, it will still contain "product", as in "really_some_product", "really_really_some_product", etc. You can see where this is going, infinite recursion.
So, you need to tell it to stop at some point, which is when the new url already starts with what you intend to prepend to the original one.
Following this, since there's a case in which we don't change anything, we should also not redirect.
var url = window.location.href,
prepend_to_url = "https://example.com/?modal-link=",
url_new = false;
if (url.indexOf(prepend_to_url) == 0) {
// url starts with what we prepend
// so do nothing
} else if(url.indexOf("product") > -1) {
url_new = prepend_to_url + url;
}
if (url_new) { // don't redirect unless we've done something above
window.location.href = url_new;
}
A more concise version of the code above could look like this:
var url = window.location.href,
prepend_to_url = "https://example.com/?modal-link=",
url_new = false;
if (url.indexOf(prepend_to_url) == -1 // url doesn't start with what we prepend
&& url.indexOf("product") > -1 // and our condition is met
) {
url_new = prepend_to_url + url;
}
url_new && (window.location.href = url_new); // equivalent to an "if" statement
What you need is to get the query parameter part of the url by using substr with index of ? to the end of the url
var url_new;
if(window.location.href.indexOf("product") > -1) {
var url = window.location.href.substr(window.location.href.indexOf("?") +1, window.location.href.length);
var newValue = 10;
url_new = 'https://example.com/?modal-link=' + newValue + "&" + url
}
console.log(url_new);
You should initilize the url_new and change it for some condition:
let url_new = window.location.href
if(window.location.href.indexOf("product") > -1) {
url_new = 'https://example.com/?modal-link=' + window.location.href;
}
window.location.href = url_new;

background.js is no longer accessible after iframe is loaded in background.html

In background.js, I injected an iframe:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.action == "doubanSearch")
test(request.title, request.year);
}
);
function test(title, year){
var frame = document.createElement('iframe');
frame.src = 'https://movie.douban.com/subject_search?cat=1002&search_text=' + title + ' '+ year;
document.body.appendChild(frame);
}
However, once the iframe is loaded, the background.js no longer responds to doubanSearch request. Is there a solution to allow background.js remain responsive to future requests even iframe is loaded?
I have checked the content.js separately and can confirm it does what I want it to be doing.
update 1
The netflixContent.js that makes requests:
var prevDOM = null;
var prevMovieTitle = 'prevMovie';
// Mouse listener for any move event on the current document.
document.addEventListener('mousemove', function (e) {
var srcElement = e.srcElement;
if (srcElement == null)
return;
if (prevDOM != srcElement){
prevDOM = srcElement;
return;
}
// find the bob-overlay class
if (srcElement.parentElement != null && srcElement.parentElement.className.startsWith('bob')) {
while (srcElement.className!="bob-overlay"){
srcElement = srcElement.parentElement;
// if srcElement is no longer a bob- class, we are out of luck here.
if (srcElement == null || !srcElement.className.startsWith('bob'))
return;
}
}
// the srcElement at this stage has to be bob-overlay class!
if (srcElement == null || srcElement.className!="bob-overlay")
return;
// now we are in the right place, get movie title and publication year
var movieTitle = srcElement.getElementsByClassName('bob-title');
var movieYear = srcElement.getElementsByClassName('year');
if (movieTitle.length != 1){
console.log('Movie title not found.', srcElement);
return;
}
if (movieYear.length != 1){
console.log('Movie year not found.', srcElement);
return;
}
// now get the title and year
movieTitle = movieTitle[0].textContent;
movieYear = movieYear[0].textContent.trim();
// if the current movie is the same as the previous movie, we return.
if (movieTitle == prevMovieTitle)
return;
// return if title is empty
if (movieTitle == '')
return;
// if movie year isn't empty, add parenthesis.
if (movieYear != '')
movieYear = '(' + movieYear + ')';
prevMovieTitle = movieTitle;
console.log('Movie found:', movieTitle, movieYear);
// replace special characters with space.
movieTitle = movieTitle.replace(/[^\w\s]/g, ' ').trim();
console.log('Movie found (special characters removed) :', movieTitle, movieYear);
// now let's send the message and start searching!
chrome.runtime.sendMessage({action: 'doubanSearch', title: movieTitle, year: movieYear});
}, false);
It is opensource hosted on github in case you need to check out the entire code. I'm really new to js and chrome extension development, so please execuse me for crappy coding :).
update 2
The background page before a request is sent:
The background page after a request is sent and iframe is loaded
Also, the background page link is no longer available from the chrome://extensions:
The site performs frame-busting (assigning top.location to an URL of the page itself) which navigates the background page to the site URL so the extension no longer has a background page. It looks like an oversight in Chrome which has been intermittently prevented in some recent versions and is about to be fixed for good in v67.
The solution is to sandbox the iframe by adding the following attribute:
frame.sandbox = 'allow-scripts';
Some sites may require more features to be allowed e.g. allow-forms, see MDN for the full list.

How to check where the code redirect in a PHP and jquery project

I am working on a open source e-shop called Prestashop.
The problem is, when I disable a module, the site will auto refresh. I would like to know which part of the code and file caused the problem.
Here is the site:
prestigefood.com.hk/zh/
Are there any way to check through browser's developer console / tools to see:
Redirect caused by JS / PHP?
Where is that part of code
The redirect is caused by a JS function inside /js/tools.js :
function autoUrl(name, dest)
{
var loc;
var id_list;
id_list = document.getElementById(name);
loc = id_list.options[id_list.selectedIndex].value;
if (loc != 0)
location.href = dest+loc;
return ;
}
Or
function autoUrlNoList(name, dest)
{
var loc;
loc = document.getElementById(name).checked;
location.href = dest + (loc == true ? 1 : 0);
return ;
}
It will be your work to find where it's called ;)

Categories

Resources