Hide page action for specific url - javascript

I am building a chrome extension for reddit.com and I am using page action for that. Now I want page_action icon to be visible only for a specific url format i.e.
http://www.reddit.com [allowed]
http://www.reddit.com/r/* [allowed]
http://www.reddit.com/r/books/comments/* [not allowed]
So, as I have mentioned above that I don't want my extension page action icon to be visible for the 3rd case involving comments url of redddit .
Currently I am using the below code in my background.js to achieve this:
function check(tab_id, data, tab){
if(tab.url.indexOf("reddit.com") > -1 && tab.url.indexOf("/comments/") == -1){
chrome.pageAction.show(tab_id);
}
};
chrome.tabs.onUpdated.addListener(check);
I have also added the below line in my manifest.json to disable the extension on the comment page
"exclude_matches": ["http://www.reddit.com/r/*/comments/*"],
So, my question is this the correct/ideal way to disable & hide an extension from a specific page/url?

Why not Zoidb- I mean, Regular Expressions?
var displayPageAction = function (tabId, changeInfo, tab) {
var regex = new RegExp(/.../); //Your regex goes here
var match = regex.exec(tab.url);
// We only display the Page Action if we are inside a tab that matches
if(match && changeInfo.status == 'complete') {
chrome.pageAction.show(tabId);
}
};
chrome.tabs.onUpdated.addListener(displayPageAction);
About the approach, I think using the onUpdated.addListener is the correct approach. As a good practice, try to show your page Action only when the tab has been loaded, unless your application requirements specify otherwise.
You can use this tool in order to generate your regular expression, and if you need help, feel free to ask again and we will help you assemble the regular expression you need.

Related

Chrome extension express url

So At the moment, My code is listening in, and I want it to listen and then see any url which belongs under "https://www.stackoverflow.com/questions/*"
How do I go about using the asterisk in my current code to make sure that all of the website can use my function ?
var regex = /^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm;
var str = ["http://www.whatevershop this is/jackets/#", "https://www.whatevershop this is/shoes/#"];
var matches_array = str.match(regex);
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.extension.getBackgroundPage().console.log(tab.url);
if (matches_array == tab.url) {
chrome.tabs.executeScript(null, {
file: "test.js"
});
}
});
The issue is when I use the asterisk (*) at the end of the slash (/) it doesn't actually let me use every single url, only the one which I enter ?
Any fixes ?
UPDATE:
Ive edited it as told, including the url and function still wont run :(
var regex = /^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/[\w#-]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm;
And the str code is var str = ["http://www.whateversiteyouneed.com/shop/#", "https://www.whateversiteyouneed.com/shop/#"];
Bare in mind on the site, there are different categories, hence why the # is in place to allow it to use all of the different locations.
I'm still wondering why the script wont run though.
It's something in the script which isn't actually seeing the new url ?
If you only want your script executed on specific urls then in your manifest add a section for content_scripts with an array of urls allowed. This is a lot simpler than using tab update events and regex and has wildcards
e.g.
"content_scripts": [
{
"matches": ["*://*.whatever.com/dogs/*"],
"js": ["test.js"],
"run_at": "document_end",
}
]
Note it's an array of arrays, so you can put as many urls in 'matches' as you wish and with the outer array, you could have different scripts on different domains. Not that that's a common use case. See extension match patterns
With this approach, the script is injected automatically and by default is inject once the page is idle, which is usually equivalent to after document ready. I usually use document_end if my code is to execute immediately. If the code will be invoked by a message from the background, e.g. by context menus, you can load at start.

JavaScript browser navbar event

I want to prevent users to navigate to URLĀ“s that are not accessed through html element. Example:
Actually navigating on: myweb.com/news
And I want to navigate to myweb.com/news?article_id=10 by writing this in the browser navigation bar to avoid pressing any element (like <a>).
When the user writes myweb.com/news?article_id=10 in the browser url, at the moment he presses enter, the browser should not allow him to navigate to the url.
I have tried:
//This wont work since jquery does not support it
$(window.location.href).on('change', function() {
//Here check if href contains '?'
alert("Not allowed");
});
//Neither works, doesnt do anything
$(window).on('change', function() {
alert("Not allowed");
});
References:
there is something similar asked here On - window.location.hash - Change?, but im interested in the 'parameter' version of that question.
There are some known solutions :
) Each time a user click a link - you save the page value to a cookie.
Later , at the server- you check that interval ( value-1 ... value+1).
) You can also save to a hidden field and check that value in the server.
So let's say a user is on page 3. ( the server serve that page - so a cookie/hidden value with value 3 is exists)
now he tries to go to page 10 :
you - in the server side - reads the cookie + requested Page number. if the interval is bigger than 1 - then you deny that request.
Try adding an event listener:
window.addEventListener('popstate', function(event)
{
var location = document.location;
var state = JSON.stringify(event.state);
});
To check the URL, The best thing would be to match it against a regex like:
if (url.match(/\?./)) {
// do not allow access
}
You might need to extend this, depending on other URL's that you need to forbid access to.

chrome.tabs.executeScript and injection only into pages that pass matches filter in manifest.json

I'm attempting to perform programmatic injection of my content script into open tabs after my Chrome extension is reloaded or updated.
My script may call the following method for an arbitrary tab:
var manifest = chrome.app.getDetails();
var scripts = manifest.content_scripts[0].js;
chrome.tabs.executeScript(nTabID, {
file: scripts[0]
});
This works, except when I try to load it into a page that was not supposed to have a content script running according to the matches clause in the manifest.json. I get the following exception:
Cannot access contents of url "actual-url-here". Extension manifest
must request permission to access this host.
So my question. Is there a way to parse the page URL and see if it matches matches clause from manifest.json and prevent calling chrome.tabs.executeScript for unnecessary URL?
PS. I understand that one "hacky" solution is to catch-and-ignore exceptions. So I'm not asking for it.
When you use chrome.tabs.query for a list of tabs, use the url attribute to filter by a match patterns. As of Chrome 39, this key also supports an array of match patterns. If you need to support Chrome 38 or earlier, or if you got the tabs without chrome.tabs.query, use the parse_match_pattern function from this answer to filter tabs. To use it, copy that function and include it within your (background) page (e.g. by pasting it before the following snippet).
var content_scripts = chrome.runtime.getManifest().content_scripts;
// Exclude CSS files - CSS is automatically inserted.
content_scripts = content_scripts.filter(function(content_script) {
return content_script.js && content_script.js.length > 0;
});
content_scripts.forEach(function(content_script) {
try {
// NOTE: an array of patterns is only supported in Chrome 39+
chrome.tabs.query({
url: content_script.matches
}, injectScripts);
} catch (e) {
// NOTE: This requires the "tabs" permission!
chrome.tabs.query({
}, function(tabs) {
var parsed = content_script.matches.map(parse_match_pattern);
var pattern = new RegExp(parsed.join('|'));
tabs = tabs.filter(function(tab) {
return pattern.test(tab.url);
});
injectScripts(tabs);
});
}
function injectScripts(tabs) {
tabs.forEach(function(tab) {
content_script.js.forEach(function(js) {
chrome.tabs.executeScript(tab.id, {
file: js
});
});
});
}
});
The previous snippet inserts a content script in all tabs. It is your responsibility to make sure that inserting the script does not conflict with an earlier/later instance of your script.
Mimicking the all_frames and match_about_blank functionality is slightly more complex, because the chrome.tabs.executeScript API cannot be used to target specific frames (crbug.com/63979). If you want to inject in frames as well, then you have to insert in every tab (because there might be a frame under the non-matching top-level frame that matches the URL) and check the page's URL within the content script.
Finally, note that your content script must also deal with the fact that it may run at a point different from "run_at". In particular, content scripts that rely on "run_at":"document_start" might fail to work because calling chrome.tabs.executeScript will cause a script to be injected far past the document_start phase.

Re-Direct with document.url.match

My goal is to redirect my website to (/2012/index.php)
ONLY IF the user goes to ( http://www.neonblackmag.com )
ELSE IF
the user goes to ( http://neonblackmag.com.s73231.gridserver.com ) they will not be re-directed... ( this way i can still work on my website and view it from this url ( the temp url )
I have tried the following script and variations, i have been unsuccessful in getting this to work thus far....
<script language="javascript">
if (document.URL.match("http://www.neonblackmag.com/")); {
location.replace("http://www.neonblackmag.com/2012"); }
</script>
This should work:
<script type="text/javascript">
if(location.href.match(/www.neonblackmag.com/)){
location.replace("http://www.neonblackmag.com/2012");
}
</script>
You should use regular expression as an argument of match (if you're not using https you can drop match for http://...
In your solution the semicolon after if should be removed - and I think that's it, mine is using location.href instead of document.URL.
You can also match subfolders using location.href.match(/www.neonblackmag.com\/subfolder/) etc
Cheers
G.
document.url doesn't appear to be settable, afaict. You probably want window.location
<script type="text/javascript">
if (window.location.hostname === "www.neonblackmag.com") {
window.location.pathname = '/2012';
}
</script>
(Don't use language="javascript". It's deprecated.)
Anyone at any time can disable JavaScript and continue viewing your site. There are better ways to do this, mostly on the server side.
To directly answer your questions, this code will do what you want. Here's a fiddle for it.
var the_url = window.location.href;
document.write(the_url);
// This is our pretend URL
// Remove this next line in production
var the_url = 'http://www.neonblackmag.com/';
if (the_url.indexOf('http://www.neonblackmag.com/') !== -1)
window.location.href = 'http://www.neonblackmag.com/2012/index.php';
else
alert('Welcome');
As I said, this can be easily bypassed. It'd be enough to stop a person who can check email and do basic Google searches.
On the server side is where you really have power. In your PHP code you can limit requests to only coming from your IP, or only any other variable factor, and no one can get in. If you don't like the request, send them somewhere else instead of giving them the page.
header('Location: /2012/index.php'); // PHP code for a redirect
There are plenty of other ways to do it, but this is one of the simpler. Others include, redirecting the entire domain, or creating a test sub domain and only allow requests to that.

Changing browser windows with window.location in javascript

I have a web site that is in two languages, English and French. now i do not know java-script, I created a code for showing different pictures using javascript depending on which language u want to use.
So if you are on the www.my-site.com/en/ you will see En_pic_ pictures same goes for the opposite.
/*These are the Popup images for the English and French portal */
var url1 = 'http://www.my-site.com/fr/';
var url2 = 'http://www.my-site.com/en/';
MagnifImage.setup(
if (window.location = 'url2'){
"En_pic_1", "/images/1.png","",
"En_pic_2", "/img/content/tracking_instructions/2.png", "",
"En_pic_3", "/img/content/tracking_instructions/3.png", "",
"En_pic_4", "/img/content/tracking_instructions/4.png", "",
}else{
"Fr_pic_1", "/img/content/tracking_instructions/1_fr.png", "",
"Fr_pic_2", "/images/mon-compte.png","",
"Fr_pic_3", "/img/content/tracking_instructions/3_fr.png","",
"Fr_pic_4", "/img/content/tracking_instructions/4_fr.png",""
}
);
Everything works but if I am on the other language page I get an alert box saying there is no Fr_pic_1 or En_pic_1.(depending on the current page I am in) The code I found to accomplish this as follows:
if( !(objRef.trigElem=document.getElementById( idParts[0] )) )
alert("There is no element with the ID:'"+idParts[0]+"'\n\nCase must match exactly\n\nElements must be located ABOVE the script initialisation.");
else
{
if(objRef.trigElem.parentNode && objRef.trigElem.parentNode.tagName=='A')
objRef.trigElem=objRef.trigElem.parentNode;
objRef.classId=idParts[1] || "MagnifImage" ;
objRef.imgObj=new Image();
objRef.imgObj.imgIndex=i;
objRef.imgObj.hasLoaded=0;
its a code I found at http://scripterlative.com?magnifimage
Please help....
You need to fix multiple things:
You must use == or === for comparison. A single = is assignment, not comparison.
You must compare to the variable name url2, not a quoted string 'url2'.
You must fix the way you pass the alternate parameters to your function MagnifImage.setup().
I switched to using window.location.href because window.location is an object and I find it better to use the actual attribute of that object you want rather than rely on an implicit conversion.
Change your code to this:
/*These are the Popup images for the English and French portal */
var url1 = 'http://www.my-site.com/fr/';
var url2 = 'http://www.my-site.com/en/';
if (window.location.href == url2) {
MagnifImage.setup("En_pic_1", "/images/1.png","",
"En_pic_2", "/img/content/tracking_instructions/2.png", "",
"En_pic_3", "/img/content/tracking_instructions/3.png", "",
"En_pic_4", "/img/content/tracking_instructions/4.png", "");
} else {
MagnifImage.setup("Fr_pic_1", "/img/content/tracking_instructions/1_fr.png", "",
"Fr_pic_2", "/images/mon-compte.png","",
"Fr_pic_3", "/img/content/tracking_instructions/3_fr.png","",
"Fr_pic_4", "/img/content/tracking_instructions/4_fr.png","");
}
Your code was likely causing many errors and thus not executing at all. You should learn how to look for javascript errors. Every browser has an error console that will show you javascript parsing or executing errors. Many browsers now have a built-in debugger than has a console in it that will also show you such information and allow you to see the exact source line causing the error. I use Chrome which has a built-in debugger which will do this. Firefox has a free add-on called Firebug that will do this.

Categories