Injecting CSS to a page as soon as possible - google-chrome-extension

My extension CSS hides youtube video (on youtube.com) from being displayed. The only issue, it loads only when the page is ready, so a noticeable 1-2 seconds of the video is being showed before it is hidden.
How can I inject CSS before the page even loads? Here is my injection code I tried with no luck:
window.addEventListener("DOMContentLoaded", function() {
path = chrome.runtime.getURL("/inject.css");
jQuery('<link/>', {
rel: 'stylesheet',
type: 'text/css',
href: path
}).appendTo('head');
});

Related

How would I make a chrome extension to block each tab's favicons?

I'm trying to replace all favicons with a Chrome extension with some Javascript. In order to do that I need to find the dom element that contains the favicon.
On most websites I can do something similar to this:
document.querySelector('link[rel="icon"]').href = "//data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
However on some websites such as apple.com, I can't figure out the dom element that contains the favicon by just viewing the page source, how would I go about blocking the favicon in that case?
I realized I was going about this all wrong. Instead of trying to replace the html element after the page was loaded, I should just block the network request which fetches the favicon.
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: ["favicon.ico", "favicon"].includes(details.url.split('/').pop().split('?')[0].split('#')[0]) };
},
{urls: ["<all_urls>"]},
["blocking"]);

Can background page use window.location

I am trying to create chrome extension that will scrap data from my webpage and then will display it in browser action window. I wanted to use background page for this, cause if i understand extensions correctly, it is only element capable of non-stop working, without need of visible tab.
The problem is, the script i wrote for background.js doesn't work properly, when i use background.js:
var location = window.location.href = 'http://localhost/index.php';
console.log(location);
manifest.json:
"background": {
"scripts": ["src/background/background.js"]
},
The answer i get is chrome-extension://some_random_text/_generated_background_page.html.
It is possible to use background pages to navigate to my webpage, then fill some forms and scrap data for later use?
This is an old question, but I recently wanted to do exactly the same.
So I'll provide an answer for others who are interested.
Setting window.location still does not work in Chrome52.
There is a workaround though. You can first fetch the web page with fetch(), and then use document.write to set the content.
This works fine, and you can then query the document and do everything you want with it.
Here is an example. (Note that I'm using the fetch API, arrow functions and LET, which all work fine now in Chrome52).
fetch("http://cnn.com").then((resp) => {
return resp.text();
}).then((html) => {
document.open("text/html");
document.write(html);
document.close();
// IMPORTANT: need to use setTimeout because chrome takes a little
// while to update the document.
setTimeout(function() {
let allLinks = document.querySelectorAll('a');
// Do something with the links.
}, 250);
});
A chrome extension has two main parts, the extension process and the browser itself. The Background Page works on the extension process. It does not have direct access and information about your webpages.
To have scripts working non-stop on your webpages, you will need to use Content Scripts.
You can then communicate between your Content Script and your Background Page using messages
contentScript.js
var location = window.location.href = 'http://localhost/index.php';
chrome.runtime.sendMessage({location: location}, function(response) {});
background.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(request.location);
});

load chrome extension popup faster

My chrome extension is very simple. After the popup is clicked an iframe is loaded. The chrome extension is slightly slow. I click the icon and it takes about a second and a half to load, and I feel like that is too slow. I'd like the popup to show instantly but have the iframe load after.. or perhaps there is an even quicker way... The site that I am iframing only has a textbox visible so in theory the popup should load pretty quickly but I'm just not getting it.
My manifest file basically is:
"browser_action": {
"default_icon": "icon128.png",
"default_popup": "main.html"
},
"background": {
"page": "main.html"
}
iframe blocks page load.
what it means is that until your iframe(s) are fully loaded the page is not considered "finished" loading, there for Chrome extension is delaying and won't show.
this blocking behavior is related to iframes behavior and not a Chrome specific issue.
to over come this, you should load your page without the iframe or iframe with src attribute of 'about:blank' and when the page is loaded add/update the iframe src attribute.
you can also add 'onLoad' event for the iframe to detect when it is finished loading to trigger your loader/spinner to hide.
here is an example in React
const Main = () => {
// state for the loader
const [loading, setLoading] = useState(true);
// state for the iframe source url
const [iframeSrc, setIframeSrc] = useState(null);
// first useEffect to see that page is fully loaded (componentDidMount in class syntax)
useEffect(() => {
setIframeSrc('https://www.your-slow-website.com');
}, []);
return (
<div style={{width: '200px'}}>
{loading && <div>LOADING...</div>}
{iframeSrc && (
<iframe onLoad={() => setLoading(false)} src={iframeSrc} style={{border: 'none', width: '100%'}} />
)}
</div>
);
};
As any async call, it may take an undeterminable amount of time to return. One clean solution would be to simply add a loading icon to your main.html. And after the iframe loads simply hide the loading icon.
It should help with the user experience as they'll be able to see at least something right after clicking the icon.

Chrome Extension that copies image URL on click

I'm brand new to making Chrome Extensions and have done the simple tutorials, but I'm having trouble finding what I need. I want the extension to allow a user to chose an image on a webpage, and then copy the URL for that image into the extension. Can anyone help me out? I'm sure if I see an example I'd get a better grasp on how extensions can interact with a page.
From what I understand of your question, I'd say you want to create a context menu item that shows up when you right-click an image. For example, in your background script, use:
chrome.contextMenus.create({
title: "Use URL of image somehow",
contexts:["image"],
onclick: function(info) {
handleImageURL(info.srcUrl);
}
});
function handleImageURL(url) {
// now do something with the URL string in the background page
}
This will add a context menu item that shows up on all pages, but only when you right-click on images. When the user selects it, the onclick handler of the menu item fires handleImageURL with the URL of the image as the argument. The URL can be processed in any way you like, e.g., saved in a localStorage list, sent to a server via Ajax, or passed in a message to a listening content script in the current tab.
EDIT with alternative:
You might want a content script that gets injected into every page. The script could bind an event listener to every image element at load time:
// in my_content_script.js...
var imgs = document.getElementsByTagName("img");
for(var i = 0, i < imgs.length; ++i) {
imgs[i].addEventListener("click", function() {
alert(this.src);
// do things with the image URL, this.src
});
}
To inject it into all subdomains of example.com, your manifest would include:
...
"content_scripts": {
"matches":["*://*.example.com/*"],
"scripts":["my_content_script.js"]
},
...
Note that this pure-JS solution doesn't attach listeners to images dynamically added after load time. To do that in your content script with jQuery, use:
$(document).on("click", " img", function() {
alert(this.src);
});
And add your jQuery file name to the scripts array in your manifest, next to my_content_script.js.
Based on this Google Chrome Extension sample:
var images = [].slice.apply(document.getElementsByTagName('img'));
var imageURLs = images.map(function(image) {
return image.src;
});
chrome.extension.sendRequest(images);
For a more detailed example (e.g. how to handle the request), you can check out this extension I wrote called Image Downloader

Using jQuery Masonry overlapping issue and Typekit

I'm using masonry and typekit. Hence, I would want the layout to not have overlapping due to image loading and at the same time render the typekit fonts without having the default fonts being shown in a flash when we first load the page.
Hence, I need javascript codes to deal with both issues: overlapping images from masonry and loading typekit fonts correctly.
I have the following codes in my javascript file that loads the masonry perfectly, but i'm unable to correctly load the typekit fonts. When the website first loads, it shows the default Times New Roman font, then it shows the typekit fonts after a flash.
How can I amend my javascript codes?
//trigger masonry and typekit
var $container = $('#wrapper');
function triggerMasonry() {
if ( !$container ) {
return
}
$container.imagesLoaded(function(){
$container.masonry({
itemSelector : '.box',
columnWidth : 240
});
});
}
$(function(){
$container = $('#wrapper');
triggerMasonry();
});
Typekit.load({
active: triggerMasonry,
inactive: triggerMasonry
});
Thanks for your code example it really helped me out and I was able to solve this just by simply removing the originaly Typekit load function that Typekit supplies:
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
After removing this my masonry worked flawless.

Resources