Can I get the value of a variable from another script? - javascript

Can I get the value of a variable from another script using content script? For example from a script on Facebook. Sorry for my english.

Your content script can inject a <script> element into the page. That injected script should read the value and use DOM events to pass the value to the content script.
In your content script:
// inject a script from the extension's files
// into the execution environment of the main page
var s = document.createElement('script');
s.src = chrome.extension.getURL("value _reader.js");
document.documentElement.appendChild(s);
document.addEventListener("valueFromPageEvent", function(event) {
console.log("the content script just got the value " + event.detail.val);
});
Inside value_reader.js (which we injected in the content script above), assuming we want to the read the variable foobar from the page:
var dataObj = { "val": foobar };
var storeEvent = new CustomEvent('valueFromPageEvent', { "detail": dataObj });
document.dispatchEvent(storeEvent);
N.B.: The value_reader.js script must be in your extension's list of web_accessible_resources in the manifest.

Related

How to share an object between content script and a window script?

I needed to get deeper into the page so my content script is really just an injector, like this
function injectScript(file) {
var th = document.getElementsByTagName('body')[0];
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', file);
th.appendChild(s);
}
injectScript( chrome.extension.getURL('/cs.js') );
Now I need to transport settings (stored in the content scripts local storage) into there as well during runtime. I can do it once no problem by creating another script node and adding the variable declaration and value in its innerHTML. Updating it this way doesn't work as well though.
Currently I have a hidden input added to the page and I write the value there and have the script on the other side periodically check and update the local one. This is just "ugh" and "eww" to me though. Is there any other way I can share the settings object between the two?

Set Script Source from the same file instead of a different one?

I create an iframe in a file and insert a <script> tag as its content. The Script src is loaded from a different file called test.js. Here is how it is done:
var scriptElement = document.querySelector("#your-widget");
var iframe = document.createElement("iframe");
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
var script = document.createElement("script");
iframe.contentWindow.document.appendChild(script);
script.src = "http://www.example.com/test.js";
Instead of loading the content of the script from http://www.example.com/test.js I want to take it from the same file where the above code is. This would like this:
var scriptElement = document.querySelector("#your-widget");
var iframe = document.createElement("iframe");
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
var script = document.createElement("script");
iframe.contentWindow.document.appendChild(script);
script.src = // ????
// the following JavaScript code should be placed inside the script
function mywidget() {
// some code
return true;
}
mywidget.succeeded = mywidget();
How can I set the Script Source from the same file instead of a different one?
If you literally just want to place that exact snippet in a script tag, you can just do so using .innerText.
script.innerText = 'function mywidget() { ...';
Then it will execute as is when it's inserted into the DOM. If you want to dynamically find and inject that code, read on.
There are exactly two ways to load a script on a page.
Add a <script> with the src attribute pointing to a file.
Create a <script> tag then set the contents to whatever you want to execute.
var script = document.createElement('script');
script.innerText = 'console.log("Hello, World!")';
document.body.appendChild(script);
If you want to extract part of a script and use those contents then the best you can do is load the contents via ajax and inject it using method 2.
Assuming you have jQuery (for easy AJAX work):
$.ajax({
url: 'path/to/script.js',
dataType: 'text', // make sure it doesn't get eval'd
success: function(contentsOfScript) {
// Refer to method 2
}
});
Now you can go about extracting the contents of that snippet in one of two ways:
Know exactly which line it begins on.
var lines = contentsOfScript.split('\n');
var snippet = lines.slice(lineNumber + 1); // adjust for 0 indexing
Generate a regular expression to identify where your code begins. This is rather tricky and very error prone if your snippet isn't easily distinguished from other code.
var snippet = contentsOfScript.match(/function mywidget.+/)[0];
Neither of these methods will work if you perform any minification on your code.

Running Javascript in new window.open

I'm running this function to open a new window.
function htmlNewWindow(id) {
var html = $(id).html();
var newWindow = window.open('');
newWindow.document.body.innerHTML = '<html><head><title>Hi</title> <script src="js/myScript.js"></script> </head>' + html;
}
This successfully creates a new window with the HTML in it. I have a bunch of HTML tags which when clicked run a function called Foo1. I've tried printing the entire function of Foo1 to the new HTML document, and tried putting Foo1 inside myScript.js. I see both Foo1 inside a script tag in the new window, and but neither are loaded since they are just written to the new page as HTML.
Scripts added with .innerHTML aren't executed. You need to create a script node and append it to the window's DOM.
$("#button").click(newWindow);
function newWindow(id) {
var html = $(id).html();
var win = window.open('');
win.document.head.innerHTML = '<title>Hi</title></head>';
win.document.body.innerHTML = '<body>' + html + '</body>';
var script = document.createElement('script');
script.src = 'js/myScript.js';
win.document.head.appendChild(script);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Click me</button>
This doesn't run in Stack Snippet's sandbox, here's a working jsfiddle.
Try this:
var newWindow = window.open('');
newWindow.document.createElement('script');
script.src = 'js/myScript.js';
newWindow.document.head.appendChild(script);
Just in case someone has this to be done in a link. Do the following:
Link
This opens a new window with that URL, it set the focus to that windows, and as soon as the 'load' event is triggered, it executes the code in the function. It only works with a page in the same domain.
Hope this helps ⬆✌.
Cheers 👍
Here's how you create, and then append a script file within a new window:
var fileref = document.createElement('script');
//creates script in current document
fileref.setAttribute("type", "text/javascript")
//set it to JS by "type"
fileref.setAttribute("src", filename)
//set your "src=yourFile_href_Here.js"
//Then create your newWindow as you did above, but slightly updated
//Create your function which will consume the "fileref" argument
function htmlNewWindow(fileref) {
var newWindow = window.open('');
newWindow.document.getElementsByTagName("head")[0].appendChild(fileref);
}; //right now the function is made but you still have to execute it
//Execute your function, and pass it the variable "fileref" that you set above.
htmlNewWindow(fileref);
//Within this edit you will append the head element
//with your newly created script(or any other parameterized argument)
/* Replace your filename to pass any other script */
NOTE - Opening a page residing on a different domain, if not specifically allowed, will reject instances of this due to CORS(https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
It's not a safe practice to be sending your scripts into other people's pages or allowing them in your own if your domain hasn't sent them. Also, depending on your server/technology stack you may need to configure your *-origin settings within your backend stack. See here: (https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)

Passing a variable before injecting a content script

I am working on a Chrome Extension that works mainly within a pop-up.
I would like the user to enter some text (a string) into an input field in the pop-up, and this string will serve as a "variable" in a script I would like to inject and run on a specific page.
I have tried achieving this by making a content script that will execute the script, using the following well documented way:
var s = document.createElement('script');
s.src = chrome.runtime.getURL('pageSearch.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);
Basically, I would like to pass the user's input all the way to the code in pageScript.js before executing the script on the page.
What would be the best way to approach this? I will not be getting any information back to the extension.
Thanks.
To pass a variable from the popup to the dynamically inserted content script, see Pass a parameter to a content script injected using chrome.tabs.executeScript().
After getting a variable in the content script, there are plenty of ways to get the variable to the script in the page.
E.g. by setting attributes on the script tag, and accessing this <script> tag using document.currentScript. Note: document.currentScript only refers to the script tag right after inserting the tag in the document. If you want to refer to the original script tag later (e.g. within a timer or an event handler), you have to save a reference to the script tag in a local variable.
Content script:
var s = document.createElement('script');
s.dataset.variable = 'some string variable';
s.dataset.not_a_string = JSON.stringify({some: 'object'});
s.src = chrome.runtime.getURL('pageSearch.js');
s.onload = function() {
this.remove();
};
(document.head||document.documentElement).appendChild(s);
pageSearch.js:
(function() {
var variable = document.currentScript.dataset.variable;
var not_a_string = JSON.parse(document.currentScript.dataset.not_a_string);
// TODO: Use variable or not_a_string.
})();

showing several JS variables value in chrome extensions

is it possible to get my website 2,3 js variables in an extensions i build so i will be able to see the info behind the site i build
the extension will help me develop my sites
Seeing the variables of a given website (using Content Scripts) is possible. Just inject your own content script, and create an script tag that reads your variables. You cannot use those variables, or modify them on your extension due to some limitations of what Content script can do. You can read the following docs on Communication with the embedding page.
For example the following will read a JS variable in the webpage and transfer its contents to the background page so we can let our extension deal with it. You will notice in the background page inspector, that the variable is successfully passed:
content_script.js
// JS script injection, so that we can read the JS class 'InternalJSVariable'
var postFriendMap = function() {
var textarea = document.getElementById('transfer-dom-area');
textarea.value = JSON.stringify(InternalJSVariable);
};
// Create a dummy textarea DOM.
var textarea = document.createElement('textarea');
textarea.setAttribute('id', 'transfer-dom-area');
textarea.style.display = 'none';
document.body.appendChild(textarea);
// Start injecting the JS script.
var script = document.createElement('script');
script.appendChild(document.createTextNode('(' + postFriendMap + ')();'));
document.body.appendChild(script);
// Inform our world that we have received the friend map data.
chrome.extension.sendRequest({internalVariable: textarea.value});
// Clean up since we no longer need this.
document.body.removeChild(textarea);
background.html
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.internalVariable) {
var internal_object = JSON.parse(request.internalVariable);
console.log(internal_object );
}
});

Categories

Resources