How can I disable javascript for the page that's being opened? - google-chrome-extension

I was up till 1 am last night trying to find an example of how to do this. My theory is that I'd write a function that would comment out all javascript.
The second option would be to add the url to the list of javascript settings.
Right now my extension is very simple:
function linkOnClick(info, tab) {
window.open(info.linkUrl)
}
chrome.contextMenus.create(
{title: "Load with no Javascript", contexts:["link"], onclick: linkOnClick});
This is my first extension and I'm kind of lost.
edit: let me know if I should also post the manifest.json.

edit: I can't mark this as solved for 2 days (why? who knows.), so I'll probably not remember to mark this as solved. So accept this as the official making: SOLVED.
chrome.contentSettings.javascript.set is the thing that disables javascript.
Here's the part that disables javascript.
(Google, here's what an actual example should look like):
chrome.contentSettings.javascript.set(
{'primaryPattern':AnyDomainName, /*this is a string with the domain*/
'setting': "block", /* block the domain. Can be switched to "allow" */
'scope':'regular'}, /*it's either regular or incognito*/
function(){
/*optional action you want to
take place AFTER something's been blocked'*/
});
Here's the script I used to import into my json script for my chrome extension.
var link=""
var pattern=""
function linkOnClick(info, tab) {
r = /:\/\/(.[^/]+)/;
link=info.linkUrl
pattern="http://"+link.match(r)[1]+"/*"
chrome.contentSettings.javascript.set(
{'primaryPattern':pattern,
'setting': "block",
'scope':'regular'},
function(){
window.open(link)
});
}
chrome.contextMenus.create({title: "Load with no Javascript", contexts:["link"], onclick: linkOnClick});
I couldn't tell how any of this worked by reading the developer.chrome.com page! They really need add complete working examples or allow a way for users to add examples. I can't even use it. The git hub link is what saved me.

Related

Accessing the window properties on another website by GM_xmlhttpRequest

I am currently writing a userscript for website A to access another the contents on website B. So I tried to use the GM_xmlhttpRequest to do it. However, a variable on B is written to the window property eg: window.var or responseContent.var.
However, when I tried to get the window.var, the output is undefined, which means the properties under the window variable cannot be read successfully. I guess the window object is refering to the website A but not website B, so the result is undefined (There is no window.var on A).
I am sure that the GM_xmlhttpRequest has successfully read the content of the website B because I have added console.log to see the response.responseText. I have also used the window.var to successfully visit that variable on website B by browser directly.
GM_xmlhttpRequest({
method: "GET",
url: url,
headers: {
referrer: "https://A.com"
},
onload: function (response) {
// console.log(response.responseText);
let responseContent = new Document();
responseContent = new DOMParser().parseFromString(response.responseText, "text/html");
let titleDiv = responseContent.querySelector("title");
if (titleDiv != null) {
if (titleDiv.innerText.includes("404")) {
console.log("404");
return;
} else {
console.log(responseContent.var);
console.log(window.var);
}
}
},
onerror: function (e) {
console.log(e);
}
});
I would like to retrieve content window.var on website B and show it on the console.log of A
Please help me solve the problem. Thank you in advance.
#wOxxOm's comments are on point. You cannot really get the executed javascript of another website like that. One way to go around it is to use <iframe> and post message, just like #wOxxOm said. But that may fail if the other website has policy against iframes.
If this userscript is just for your use, another way is to have two scripts, one for each website and have them both open in browser tabs. Then again you can use postMessage to have those two scripts communicate the information. Dirty solution for your second userscript would be to just post the variable info on regular interval:
// Userscript for website-b.com
// needs #grant for unsafe-window to get the window.var
setInterval(()=>{postMessage(unsafeWindow.var, "website-a.com");}, 1000);
That would send an update of var's value every second. It's not very elegant, but it's simple and works. For a more elegant solution, you may want to first postMessage from website a that will trigger postMessage(unsafeWindow.var, "website-a.com"). Working with that further, you will soon find yourself inventing an asynchronous communication protocol.
Alternatively, if the second website is simple, you can try to parse the value of var directly from HTML, or wherever the value is coming from. That's a preferred solution, but requires reverse-engineering on your part.

How do I add button in NetSuite client script and use it as trigger for script function?

I'm trying to add a button to the current record with the Client Script button definition on a script record, but for some reason it's not finding my function. I'm returning my function tryThisand there is a button on the page which I created on the script record with the function tryThis defined in the appropriate field, but the code doesn't run. Here's my script:
define (['N/currentRecord','N/search','N/record'] ,
function(currentRecord,search,record) {
function tryThis(context){
log.debug({
title: 'try this',
details: 'try this'
});
}
function pageInit(context) {
}
return {
pageInit: pageInit,
tryThis: tryThis
};
});
Nothing happens :(
Yes, the script is deployed.
How can I use this button on a client script??
This doesn't exactly answer your question directly, but I hope it may help. I tested this, and there appears to be nothing wrong with the way you've set it up - the only thing that seems to be not working is the log module, which I've come across before in client scripts.
Try running your function using a console.log() or alert() instead (both work for me).
Hopefully someone with more detailed knowledge of the N/log module's design and behavior will chip in, as the documentation seems to indicate that this should work.
At the bottom of your Client Script record in Edit mode you will find where you can easily set the button and function to call.

Sammy.js with Knockout.js Not Running Route With Every URL Change

I have a single Sammy route that recognizes an arbitrary number of parameters. The route looks like this:
get(/^\/(?:\?[^#]*)?#page\/?((?:[^\:\/]+\:[^\:\/]+\/?)*)$/g, function() {
var params = {};
var splat = this.params.splat[0];
var re = /([^\:\/]+)\:([^\:\/]+)/g;
match = true
while(match = re.exec(splat)) {
params[match[1]] = match[2];
}
self.loadData(params);
});
This code works. What it does is it recognizes routes of the pattern #page/param1:value1/param2:value2/ for an arbitrary number of parameters. My loadData function has default values for many of these parameters. I'm confident there isn't a problem with the actual loading of the pages, since it works 100% on many computers in many browsers. However, it has weird behavior on my Android's browser and on my friend's Mac's Safari and Chrome (works on my PC's Chrome). I've noticed that these are Webkit browsers.
The behavior is that the route runs correctly for the first URL change, then won't for the next URL change (although the URL in the browser bar does indeed always change), then it'll work again for the third one, and won't for the fourth. That is, it works every other time. This seems like very strange behavior to me, and I'm at a loss as to how to debug this. For certain links, I was able to run a hack such that on click I set the window location to the URL and forcefully run the sammy code with runRoute('get', url);. It's impractical to have to add this for every click event on the page, and that doesn't really account for all URL changes anyway. Is there something I can do to debug why my route isn't being run every time the URL is changing?
For those of you who encounter similar behavior, on every other click in the above-mentioned browsers, this.params.splat was undefined. It's supposed to be set to the matched part of the URL (e.g. /#page/param1:value1/).
The hack I came up with to deal with this is to add this to the top of the get route:
if(this.params.splat === undefined) {
app.unload().run();
return;
}
This doesn't get to the root of the problem, it's just a hack that allows it to re-run the routes so that params.splat isn't undefined the next time through. If anyone has more information on what is going on, I'd be interested.

How to modify dashlets to auto-refresh?

Is there a simple way to modify a dashlet to automatically re-load itself periodically?
I am particularly thinking of the "My Tasks" dashlet - we are using pooled review workflows, so tasks may come and go all the time as they are created and then are claimed.
It may be frustrating for users to keep clicking on tasks that turn out to have already been claimed - or having to remember to keep re-loading their Dashboard page. I'd prefer the dashlet to refresh on a timed interval so it's always reasonably up to date.
In order to do this you will need to add a new capability to the client-side class Alfresco.dashlet.MyTasks (docs, source) found in the file components/dashlets/my-tasks.get.js. First you will need to add a new method to the prototype extension specified as the second parameter in the YAHOO.lang.augmentObject() call, e.g.
...
}, // end of last OOTB function - add a comment here
// begin changes
reloadData: function MyTasks_onReady()
{
this.widgets.alfrescoDataTable.loadDataTable(
this.options.filters[this.widgets.filterMenuButton.value]
);
}
// end changes
});
})();
It's not the ideal development environment, you can modify the JS file directly in the Share webapp, although you will also need to update the corresponding -min.js file.
Once you've done this, check that it works by running the following line in your browser's JavaScript console
Alfresco.util.ComponentManager.findFirst("Alfresco.dashlet.MyTasks").reloadData();
If that works, then you can wire up your new method to a title bar action (see my DevCon presentation for more background info), in the dashlet web script. The method depends on whether you are using v4.2 or a previous version, but if it is the latter then you need to add some code to the dashlet's Freemarker file my-tasks.get.html.ftl (under WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/dashlets).
In that file you should see some JavaScript code inside a <script> tag, this sets up an instance of the client-side class and some utility classes, the contents of which you can replace with the following, to add your custom title bar action.
(function()
{
var dashlet = new Alfresco.dashlet.MyTasks("${jsid}").setOptions(
{
hiddenTaskTypes: [<#list hiddenTaskTypes as type>"${type}"<#if type_has_next>, </#if></#list>],
maxItems: ${maxItems!"50"},
filters:
{<#list filters as filter>
"${filter.type?js_string}": "${filter.parameters?js_string}"<#if filter_has_next>,</#if>
</#list>}
}).setMessages(${messages});
new Alfresco.widget.DashletResizer("${id}", "${instance.object.id}");
var refreshDashletEvent = new YAHOO.util.CustomEvent("onDashletRefresh");
refreshDashletEvent.subscribe(dashlet.reloadData, dashlet, true);
new Alfresco.widget.DashletTitleBarActions("${args.htmlid}").setOptions(
{
actions:
[
{
cssClass: "refresh",
eventOnClick: refreshDashletEvent,
tooltip: "${msg("dashlet.refresh.tooltip")?js_string}"
},
{
cssClass: "help",
bubbleOnClick:
{
message: "${msg("dashlet.help")?js_string}"
},
tooltip: "${msg("dashlet.help.tooltip")?js_string}"
}
]
});
})();
You will need to add some styles for the class name specified, in the dashlet's CSS file my-tasks.css, such as the following
.my-tasks .titleBarActions .refresh
{
display: none;
background-image: url('refresh-icon.png');
}
The icon file (here is one you could re-use) must be in the same directory as the CSS file.
Lastly you'll need to define the label dashlet.refresh.tooltop used for the title bar action's tooltip. You can do this in the dashlet web script's .properties file.
For a similar example, check out the source of my Train Times dashlet, which features a refresh title bar action.
In some ways it's actually easier to define your own dashlets than it is to extend the Alfresco-supplied ones, but if you have the option of using 4.2.x, the new method allows you to extend the existing components without duplicating any code, which obviously makes upgrades much easier.

How to use the experimental offscreenTab API?

I've been searching for examples and reference and have come up with nothing. I found a note in offscreenTab source code mentioning it cannot be instantiated from a background page (it doesn't have a tab for the offscreenTab to relate to). Elsewhere I found mention that popup also has no tie to a tab.
How do you successfully create an offscreenTab in a Chrome extension?
According to the documentation, offscreenTabs.create won't function in a background page. Although not explicitly mentioned, the API cannot be used in a Content script either. Through a simple test, it seems that the popup has the same limitation as a background page.
The only leftover option is a tab which runs in the context of a Chrome extension. The easiest way to do that is by using the following code in the background/popup:
chrome.tabs.create({url: chrome.extension.getURL('ost.htm'), active:false});
// active:false, so that the window do not jump to the front
ost.htm is a helper page, which creates the tab:
chrome.experimental.offscreenTabs.create({url: '...'}, function(offscreenTab) {
// Do something with offscreenTab.id !
});
To change the URL, use chrome.experimental.offscreenTabs.update.
offscreenTab.id is a tabId, which ought to be used with the chrome.tabs API. However, at least in Chrome 20.0.1130.1, this is not the case. All methods of the tabs API do not recognise the returned tabID.
A work-around is to inject a content script using a manifest file, eg:
{"content_scripts": {"js":["contentscript.js"], "matches":["<all_urls>"]}}
// contentscript.js:
chrome.extension.sendMessage({ .. any request .. }, function(response) {
// Do something with response.
});
Appendum to the background page:
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
// Instead of checking for index == -1, you can also see if the ID matches
// the ID of a previously created offscreenTab
if (sender.tab && sender.tab.index === -1) {
// index is negative if the tab is invisible
// ... do something (logic) ...
sendResponse( /* .. some response .. */ );
}
});
With content scripts, you've got full access to a page's DOM. But not to the global object. You'll have to inject scripts (see this answer) if you want to run code in the context of the page.
Another API which might be useful is the chrome.webRequest API. It can be used to modify headers/abort/redirect requests. Note: It cannot be used to read or modify the response.
Currently, the offscreenTabs API is experimental. To play with it, you have to enable the experimental APIs via chrome://flags, and add "permissions":["experimental"] to your manifest file. Once it's not experimental any more, use "permissions":["offscreenTabs"].

Resources