I am trying to make an extension which will run on tumblr.com/dashboard which will hide any div which is "promoted" (i.e. a blog I don't follow, which isn't a paid promotion)
I have the following code in hidestuff.js
$(document).ready(function() {
var hide = $( "div:has(.post_dismiss)" );
for (var i = 0; i < hide.length; i++) {
var div = hide[i].getAttribute('id');
var id = "#"+div;
$(id).hide();
}
});
And the following is what I have in my manifest.json
{
"manifest_version": 2,
"name": "I'm Not Following You",
"version": "0.1",
"content_scripts": [
{
"matches": [
"https://tumblr.com/dashboard", "http://tumblr.com/dashboard"
],
"js": ["hidestuff.js"]
}
]
}
Tumblr uses jQuery, hence me not including a copy.
I have tested the code (by copying the DOM from my Tumblr dashboard, which included the divs I am trying to hide) and the tests worked. However, adding it to Chrome didn't work.
This is my first attempt at making an extension, and I followed an simple tutorial. It may have been outdated, but there was no date on the tutorial, but I don't know where I am going wrong.
Update your matches field in manifest.json, because "https://tumblr.com/dashboard" doesn't match "https://www.tumblr.com/dashboard"
Use your own jquery. Chrome extension doesn't have access to any JavaScript variables or functions created by the page.
So the final version would be:
manifest.json
{
"manifest_version": 2,
"name": "I'm Not Following You",
"version": "0.1",
"content_scripts": [
{
"matches": [
"https://www.tumblr.com/dashboard",
"http://www.tumblr.com/dashboard"
],
"js": [
"jquery.js",
"hidestuff.js"
]
}
]
}
hidestuff.js
$(document).ready(function () {
var hide = $("div:has(.post_dismiss)");
for (var i = 0; i < hide.length; i++) {
var div = hide[i].getAttribute('id');
var id = "#" + div;
$(id).hide();
}
});
Content scripts do not run in the same context as scripts on the page. You will need to include every library you want to use in your package and in the content scripts manifest section.
https://developer.chrome.com/extensions/content_scripts#execution-environment
Related
I am developing a simple Chrome extension, that does something when a password-input box is focused. I'm using following content script to achieve the same (code is simplified for asking this question). The code does not work on pages like https://accounts.google.com/ but it works perfectly for pages like https://www.linkedin.com/. Is it because of some Javascript/JQuery conflicts? Or some other reason? Please help. I tried using noConflict api, but it didn't help.
Content script:
var inputs = document.getElementsByTagName('input');
function foo() {
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type.toLowerCase() == 'password')
inputs[i].addEventListener("focus", bar);
}
}
function bar() {
alert(1);
}
foo();
Above script finds input elements of type passwords, but does not add event listener.
Manifest:
{
"manifest_version": 2,
"name": "MyExtension",
"version": "1.0",
"options_page": "options.html",
"browser_action": {
"default_icon": "img/abcd.png",
"default_title": "MyExtension",
"default_popup": "popup.html"
},"icons": { "16": "img/abcd16.png",
"48": "img/abcd48.png",
"128": "img/abcd128.png" },"description":"abcd abcd",
"permissions": [
"storage","tabs"
],
"content_scripts": [
{
"matches": ["<all_urls>"
],
"js": ["js/content.js","js/jquery.1.8.3.min.js"],
"css": ["css/style.css"],
"run_at": "document_end",
"all_frames": true
}
],"web_accessible_resources": [
"img/*.png",
"css/*.css"
]
}
Have you considered that the input field you seek doesn't exist by the time that the script executes? https://accounts.google.com/ is a dynamic form, the password field is created long after the page is loaded (document_end) and therefore long after you collect inputs.
In addition to binding the handler to existing elements, you need to watch for new ones being added. I would suggest using mutation-summary library with a query {element: "input[type=password]"}, but if you don't want to involve a library the basic building block to look at is MutationObserver.
I am writing a Chrome Extension mainly for Pull Requests on Github Enterprise and have ran into an issue. When the page is loaded via a refresh or direct entering of the url from your browser it runs, when it is ran from clicking a link within Github it does not.
For instance if you go to this page with Pull Requests and click into one of them it will not run. But if you refresh that same page it will run.
manifest.json
{
"name": "Github Sample",
"manifest_version": 2,
"version": "0.0.1",
"description": "Sample",
"permissions": [
"tabs", "<all_urls>",
"http://github.com/*"
],
"content_scripts": [
{
"matches": [ "https://github.com/*" ],
"js": ["github.sample.js"],
"run_at": "document_end"
}
]
}
github.sample.json
// ==UserScript==
// #author Jacob Schoen
// ==/UserScript==
alert("Extension has Ran");
To make this easier I have pushed this to github.
Any ideas on how to address this?
GitHub site uses jquery-pjax library (see How to make github style page transitions by pjax).
Basically you only need to run the content script once and attach pjax event handlers inside an injected <script> element code which will be reusing a jQueryor $ variable of the site.
In those handlers you can send a message with document.dispatchEvent to your content script that will receive it in its window.addEventListener("blabla", ...)
or you can allow the access to chrome.runtime.sendMessage on the github site in manifest.json so that page-injected code will be able to send a message that can be received by the extension in chrome.runtime.onMessageExternal listener.
Alternatively you can use chrome.webNavigation.onHistoryStateUpdated in the background script but that will cause a warning during the installation that the extension can "Read your browsing history" which is a global permission unlike the content script solution.
The working example I came up with, in case it helps anyone else.
manifest.json
{
"name": "Github Sample",
"manifest_version": 2,
"version": "0.0.1",
"description": "Sample",
"permissions": [
"activeTab",
"tabs", "<all_urls>",
"http://github.com/*"
],
"content_scripts": [
{
"matches": [ "https://github.com/*" ],
"js": ["github.sample.js"],
"run_at": "document_idle"
}
],
"web_accessible_resources": ["inject.js"]
}
github.sample.js
// ==UserScript==
// #author Jacob Schoen
// ==/UserScript==
function myAlert() {
alert("Extension has Ran");
}
window.addEventListener("pageLoadTransition", myAlert);
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('inject.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
//still have to load this one for direct page loads
myAlert();
inject.js
$(document).on('pjax:success', function() {
var evt=document.createEvent("CustomEvent");
evt.initCustomEvent("pageLoadTransition", true, true, null);
document.dispatchEvent(evt);
})
I also updated the Github repository with the working example.
I wrote a short content script, which stops a particular site from creating new windows for link clicks.
This is my first Chrome extension, and I've scored this website and the internet for a reason why it won't run, but I can't find any. I'm probably making a fundamental amateur mistake somewhere.
Manifest.json:
{
"manifest_version": 2,
"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts":[
{
"matches": ["*://www.darienps.org/dhs/*"],
"js": ["jquery.js", "makeNormalLinks.js"],
"run_at": "document_end"
}
]
}
I tested the Javascript file by itself on a local version of the site, so I'm pretty sure it's fine, but just in case:
makeNormalLinks.js:
$(document).ready(function() {
$("a").each(function(){
$(this).removeAttr("onclick");
});
});
A copy of jQuery is in the same directory and doesn't seem to have any issues.
Here's the onclick code for many links on the website:
onclick="window.open(this.href,'targetWindow','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,')
Thank you for looking this over!
Edit:
I tried two of the injection methods from Rob W's response to another question linked to in the comments by Teepeemm.
Here's the new code for Method 1:
Manifest.json:
{
"manifest_version": 2,
"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts":[
{
"matches": ["*://www.darienps.org/dhs/*"],
"js": ["jquery.js", "scriptLauncher.js"]
}
],
"web_accessible_resources": ["makeNormalLinks.js"]
}
scriptLauncher.js:
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('makeNormalLinks.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
Method 2a:
(Uses old Manifest.js)
makeNormalLinks.js:
var actualCode = ['$(document).ready(function(){',
'$("a").each(function(){',
'$(this).removeAttr("onclick");',
'});',
'});'].join('\n');
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
Unfortunately, neither method seems to work. I'm extremely grateful to those who commented and think we're getting close to an answer.
Solution:
Manifest.json:
{
"manifest_version": 2,
"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts":[
{
"matches": ["*://www.darienps.org/dhs/*"],
"js": ["makeNormalLinks.js"]
}
]
}
makeNormalLinks.js:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, true);
Thanks you, Scott and all who commented!
Using the onclick attribute has many weird side effects. A more up to date approach would be to add a listener to the document that filters unwanted events. Like:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, true);
The true argument is important (see event capture). This will block all click event listeners from firing, but the default click action will still be triggered.
I was having a similiar issue getting the content script to fire in Google Mail. I stumbled upon a page that recommended using the "hashchange" event.
// Event listener
window.addEventListener("hashchange", function () {
alert("hashchanged");
}, false);
I have absolutely no experience in chrome extension developing, but for some punctual need, I have to modify an existing extension, in order to ask the user to enter a port of connection for a socket.
It is composed of a manifest json file and two content scripts, one of which is the jquery library. I think it should be very simple, but after some google research, I could not find the direct answer to my problem.
manifest.json
{
"name": "MyExtension",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [
{
"matches": ["http://myurl.com/"],
"css": ["style.css"],
"js": ["jquery-1.7.2.min.js", "script.js"]
}
]
}
script.js
(function() {
var sock = null;
function connect() {
if (sock !== null) {
return;
}
sock = new WebSocket('ws://localhost:1234/'));
[...]
}
[...]
})();
Just to be clear, my goal is to replace the '1234' port for the socket with a customized port set by the user through a dialog window.
Thanks by advance for your help,
Romain Laroche
I am trying to integrate CodeMirror's syntax highlighting with a textarea using chrome extensions.
Here is my test.js...
var srcArray = ["lib/codemirror.js",
"lib/util/matchbrackets.js",
"lib/util/continuecomment.js",
"mode/htmlmixed/htmlmixed.js",
"mode/xml/xml.js",
"mode/javascript/javascript.js",
"mode/css/css.js",
"mode/clike/clike.js",
"mode/php/php.js"];
function AddScript(value)
{
var s = document.createElement("SCRIPT")
s.src = chrome.extension.getURL(value);
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
}
srcArray.forEach(AddScript);
... and manifest.json:
{
"name":"Test",
"description":"Test description",
"version":"1.0",
"manifest_version": 2,
"browser_action": {
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": ["file:///*Test*"],
"js": ["test.js"]
}
],
"web_accessible_resources": ["lib/codemirror.js",
"lib/util/matchbrackets.js",
"lib/util/continuecomment.js",
"mode/htmlmixed/htmlmixed.js",
"mode/xml/xml.js",
"mode/javascript/javascript.js",
"mode/css/css.js",![enter image description here][1]
"mode/clike/clike.js",
"mode/php/php.js"]
}
And here is the issue I am facing:
<script>...</script> are being added to the page, however when the last one is added they all disappear.
I suspect this has someting to do with security mechanisms introduced in 2nd version of the manifest. I cannot however figure out what is missing.
Your advice would be greatly appreciated, thanks.