Chrome open address in tab - google-chrome

I am trying to create a simple adult filter to get my feet wet in Chrome extension building.
Basically, I have a block list and a redirect list, everything works great and the correct parts fire when the user enters one of block list's domains, and now i want to redirect to google when that happens, so I used this code (that I got after searching Google) :
if (blocked) {
up = new Object();
up.url = chrome.extension.getURL("http://www.google.com");
chrome.tabs.update(tab.id, up);
but that seems to be code only to open files locally.
How do I open the URL instead?
Thanks!

Since "http://www.google.com" is not an extension resource, just use:
up.url = "http://www.google.com";

Related

Programmatic injection on nested iframes in extension page

Summary: I need to find a way to accomplish with programmatic injection the same exact behaviour as using content_scripts > matches with "all_frames": true on a manifest. Why? because it is the only way I've found of injecting iframe's content in an extension page without having Cross-Origin errors.
I'm moving to optional_permissions on a Chrome extension and I'm on a dead end.
What I want:
Move this behaviour to optional_permissions in order to be able to add more hosts in the future. With the current code, by adding one new host on content_scripts > matches the extension is disabled by Chrome.
For the move, I removed content_scripts in the manifest and I added "optional_permissions": ["*://*/"],. Then, I successfully implemented a dialog asking new permissions to the user with chrome.permissions.request.
As I said before, the problem is how to inject the iframe's content in an extension page.
What I've tried:
chrome.declarativeContent.RequestContentScript (mentioned here) with allFrames: true. I can only see the script running if I enter the URL directly, nothing happens when that URL is set in an iframe.
chrome.tabs.onUpdated: url is undefined for an extension page. Also, the iframe url is not detected.
Call chrome.tabs.executeScript with allFrames: true as soon as I load the first iframe. By doing this I get an exception Cannot access contents of the page. Extension manifest must request permission to access the respective host. and the "respective host" is chrome-extension://, which is not a valid host if you want to add it to the permissions.
I'm lost. I couldn't find a way to simulate the same behaviour as content_scripts > matches with programmatic injection.
Note: using webNavigation API is not an option since the extension is live and it has thousands of users. Because of this, I can not use the frameId property for executeScript. Thus, my only option with executeScript was to inject all frames but the chrome-extension host issue do not let me continue.
Update: I was able to accomplish what I wanted but only on an HTTP host. I used chrome.tabs.executeScript (option 3).
The question remains on how to make this work on an extension page.
You cannot run content scripts in any extension page, including your own.
If you want to run code in a subframe of your extension page, then you have to use frameId. There are two ways to do this, with and without webNavigation.
I've put all code snippets in this answer together (with some buttons to invoke the individual code snippets) and shared it at https://robwu.nl/s/optional_permissions-script-subframe.zip
To try it out, download and extract the zip file, load the extension at chrome://extensions and click on the extension button to open the test page.
Request optional permissions
Since the goal is to programmatically run scripts with optional permissions, you need to request the permission. My example will use example.com.
If you want to use the webNavigation API too, include its permission in the permission request too.
chrome.permissions.request({
// permissions: ['webNavigation'], // uncomment if you want this.
origins: ['*://*.example.com/*'],
}, function(granted) {
alert('Permission was ' + (granted ? '' : 'not ') + 'granted!');
});
Inject script in subframe
Once you have a tab ID and frameId, injecting scripts in a specific frame is easy. Because of the tabId requirement, this method can only work for frames in tabs, not for frames in your browserAction/pageAction popup or background page!
To demonstrate that code execution succeeds, my examples below will call the next injectInFrame function once the tabId and frameId is known.
function injectInFrame(tabId, frameId) {
chrome.tabs.executeScript(tabId, {
frameId,
code: 'document.body.textContent = "The document content replaced with content at " + new Date().toLocaleString();',
});
}
If you want to run code not just in the specific frame, but all sub frames of that frame, just add allFrames: true to the chrome.tabs.executeScript call.
Option 1: Use webNavigation to find frameId
Use chrome.tabs.getCurrent to find the ID of the tab where the script runs (or chrome.tabs.query with {active:true,currentWindow:true} if you want to know the current tabId from another script (e.g. background script).
After that, use chrome.webNavigation.getAllFrames to query all frames in the tab. The primary way of identifying a frame is by the URL of the page, so you have a problem if the framed page redirects elsewhere, or if there are multiple frames with the same URL. Here is an example:
// Assuming that you already have a frame in your document,
// i.e. <iframe src="https://example.com"></iframe>
chrome.tabs.getCurrent(function(tab) {
chrome.webNavigation.getAllFrames({
tabId: tab.id,
}, function(frames) {
for (var frame of frames) {
if (frame.url === 'https://example.com/') {
injectInFrame(tab.id, frame.frameId);
break;
}
}
});
});
Option 2: Use helper page in the frame to find frameId
The option with webNavigation looks simple but has two main disadvantages:
It requires the webNavigation permission (causing the "Read your browsing history" permission warning)
The identification of the frame can fail if there are multiple frames with the same URL.
An alternative is to first open an extension page that sends an extension message, and find the frameId (and tab ID) in the metadata that is made available in the second parameter of the chrome.runtime.onMessage listener. This code is more complicated than the other option, but it is more reliable and does not require any additional permissions.
framehelper.html
<script src="framehelper.js"></script>
framehelper.js
var parentOrigin = location.ancestorOrigins[location.ancestorOrigins.length - 1];
if (parentOrigin === location.origin) {
// Only send a message if the frame was opened by ourselves.
chrome.runtime.sendMessage(location.hash.slice(1));
}
Code to be run in your extension page:
chrome.runtime.onMessage.addListener(frameMessageListener);
var randomMessage = 'Random message: ' + Math.random();
var f = document.createElement('iframe');
f.src = chrome.runtime.getURL('framehelper.html') + '#' + randomMessage;
document.body.appendChild(f);
function frameMessageListener(msg, sender) {
if (msg !== randomMessage) return;
var tabId = sender.tab.id;
var frameId = sender.frameId;
chrome.runtime.onMessage.removeListener(frameMessageListener);
// Note: This will cause the script to be run on the first load.
// If the frame redirects elsewhere, then the injection can seemingly fail.
f.addEventListener('load', function onload() {
f.removeEventListener('load', onload);
injectInFrame(tabId, frameId);
});
f.src = 'https://example.com';
}

Posting a status message to Facebook?

There's so many questions regarding Facebook's sharer.php, but they're all out of date. At first Facebook depreciated it, but according to FB's dev documentation it's now back. (Edit: And now it's going again...?)
You used to be able to use it like this:
http://www.facebook.com/sharer/sharer.php?u=<url to share>&t=<message text>
But the documentation now only mentions this:
https://www.facebook.com/sharer/sharer.php?u=<url to share>
Is it possible to set some pre-entered text into the dialogue box that appears when sharing a link on Facebook?
Thanks.
The Share dialog takes only the URL to share as parameter, nothing else (title, description, picture, …) any more. It fetches this data from the URL itself, from the Open Graph meta elements embedded into the document, or it takes a “guess” from the content if those are not present.
And even the “older” version of the Share dialog has not been taking a pre-set message parameter for a long time now – because you are not supposed to pre-fill the message in any way when sharing something, not matter what way the share actually happens. (“Not supposed to” actually meaning, Platform Policies explicitly forbid you from doing so.)
You can of course also share links via API (rather called “posting” a link then) – and because that happens in the background, the message is a parameter you specify while doing so. But the same rules apply – the message is supposed to be created by the user themselves beforehand, which effectively means they should have typed it in somewhere before. And even there it should not have been pre-filled so that they just have to press enter or click a button.
And since they announced API v2.0, all new apps will have to go through “login review” before they will be able to ask for any advanced permission (and posting a link requires one) – and with a pre-filled message in your app’s posting flow, you will definitively not get approval. Of course, you could try to “cheat” on that, and implement the pre-filling of the message only afterwards … but again, doing so is a clear violation of Platform Policies, and will get your app blocked when you are caught doing so.
And if you are planning to do this for multiple users with the same or largely similar messages, you can assume that Facebook’s algorithms will catch that quite easily.
Just one small comment - while it is not possible to edit the text as the other comments say - it is possible to edit everything going on in that page if you can install a browser extension on your client's machines (you did not specify your use case so I am mentioning this just in case you are developing something that you are able to influence in the client machine level).
For example, with a chrome extension, you can inject scripts into facebook.com domain. in the extension manifest.json:
"content_scripts": [
{
"matches": ["https://*.facebook.com/*",
And then this might be your contnet script, where you can play around with the text by hooking up to the markeup. This example sends out analytics (facebook sharer conversion rate) and changes some text (from "share" to "upload" to facebook):
sharer = (function () {
var _ref = qs('ref') ? qs('ref') : 'unknown';
function qs(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
function isSharer() {
return location.pathname === '/sharer/sharer.php';
}
function bindEvents() {
$('button[name="share"]').click(function() {
analytics.send('fb_sharer', 'share', _ref);
});
$('#u_0_0').click(function() {
analytics.send('fb_sharer', 'cancel', _ref);
});
}
function changeText() {
console.log($('.fcw').length);
$('.fcw').text('Upload to Facebook');
}
function load() {
if (!isSharer()) return;
changeText();
analytics.send('fb_sharer', 'view', _ref);
bindEvents();
}
return {
load: load
}
})();

Google Drive Realtime API - Adding Collaborative list

From the documentation, it says I can have a collaborative list which contains other collaborative objects, namely another collaborative list. Therefore in my "onFileLoaded" event, I have the following code:
var myRoot = doc.getModel().getRoot().get('myList');
var newList = doc.getModel().createList();
newList.push('Level2');
myRoot.push(newList);
I understand that everytime I reload the file, a new list will be added to "myList". Everything works fine except when I reload the document, that's when the API will only give me "myList" and the "newList" is gone and disappeared into thin air. If I add a string or any other data, the data will persist when I reload the document, but not adding another list to the current list. What am I doing wrong? Thanks in advance.
I am not sure why the above does not work for me, but when I moved the list adding codes out of "onFileLoaded", specifically, adding list to lists only when I click on some DOM element, everything works fine. I supposed these codes should be out of "onFileLoaded" anyways, so it's all good and hopefully someone find these useful.

Google Map V2 GIcon.shadow Image display in local development server but not from test server

I have custom marker icon (gif/png) to display on Google Map V2. I am using GICON and shadow property to set image path. The marker icons are diplaying as expected in development system. But after i deploy the system into server (Windows server 2008 r2, IIS 7.5), the icons are not displaying in some PC (not all). For some users the icons are displaying but for some users it is not displaying. I really appreciate all your help on this regard.
The code used is below :
var cm_baseIcon = new GIcon();
if (Records[i].Act == '1')
cm_baseIcon.shadow = "images/img/Markers/green.gif";
else
cm_baseIcon.shadow = "images/img/Markers/red.gif";
cm_baseIcon.iconSize = new GSize(27, 27);
cm_baseIcon.iconAnchor = new GPoint(9, 34);
cm_baseIcon.infoWindowAnchor = new GPoint(0, 0);
cm_baseIcon.infoShadowAnchor = new GPoint(13, 27);
var markerOpts = {};
var icon = new GIcon(cm_baseIcon);
markerOpts.icon = icon;
When I load your test page, I don't see any markers. Should the page create some markers when first loaded like this, or do I need to interact with the page in some way to get it to display any markers?
I set a breakpoint inside the initialize() function. Your Records variable is an empty array, i.e. []. So the for loop in this function that creates the markers never executes.
Do you know how to use the JavaScript debugger in a browser? It will let you figure out what is going wrong without having to ask anyone. I and other people here are happy to help, of course, but you'll make much faster progress if you can debug this on your own.
I recommend the developer tools in the Chrome browser. Here is a good introduction to the Chrome DevTools. Read through that and try out the JavaScript debugger in particular. You can stop your code and look at variables, change values, single step through the code to see what each line does, etc. This will at least double your productivity in JavaScript, and probably even more than that.

Find an element on new Page on Windows Phone 7/8

I try to instance new page and get the object on that page (for example LongListSelector) by the name.
But when I do
var currentPage = (PhoneApplicationPage)((PhoneApplicationFrame)App.Current.RootVisual).Content;
currentPage.NavigationService.Navigate(new Uri(pageUri, UriKind.Relative));
I can't get the instance of new page. The second calling of var currentPage = (PhoneApplicationPage)((PhoneApplicationFrame)App.Current.RootVisual).Content gets me the same currentPage.
How can I access the instance of new page and items on it?
I need it to implement custom item selector. When tapping on the list item_header from page1 the page2 is showing, where I can chose the right item_kind and navigate back to list1.
What you are actually looking for is passing data between pages or having a ViewModel that can be accessed from different pages and share data between them. Please have a look at the answer for that question here
It describes the different ways of sharing data between pages.
Done it with saving page instance in OnNavigateTo event into a global array.