Rectangle 27 2

Generalized code to execute in the page context from a content script

Your content script is in a different context/scope from that of page scripts (scripts that already exist in the webpage). Your content script has higher privileges than are granted to page scripts. Keeping content scripts separate from page scripts is a normal architecture for browser extensions which is done for security reasons.

In order to execute code in the page script context, you have create and insert a <script> element into the page's DOM.

function updateTask(id) {
    let newScript = document.createElement('script');
    newScript.innerHTML='updTask(' + id + ');';
    document.head.appendChild(newScript);
    //newScript.remove(); //Can be removed, if desired.
}

The added script gets run in the page context because it is now a <script> element in the DOM. The browser recognizes that a <script> element was added and evaluates it (executes the code contained) as soon as the script which inserted it is no longer processing. It does basically the same thing for any other element you add to the DOM. Because it is part of the page, the code inside the gets run in the page script context/scope.

The easiest way to maintain code which you are going to execute in the page context is to write it as a function in your content script, then inject that function into the page context. Here is some generalized code which will do that while passing parameters to the function you are executing in the page context:

This utility function, executeInPage(), will execute a function in the page context and pass any provided arguments to the function. Arguments must be Object, Array, function, RegExp, Date, and/or other primitives (Boolean, null, undefined, Number, String, but not Symbol).

/* executeInPage takes a function defined in this context, converts it to a string
 *  and inserts it into the page context inside a <script>. It is placed in an IIFE and
 *  passed all of the additional parameters passed to executeInPage.
 *  Parameters:
 *    func          The function which you desire to execute in the page. 
 *    leaveInPage   If this does not evaluate to a truthy value, then the <script> is
 *                    immediately removed from the page after insertion. Immediately
 *                    removing the script can normally be done. In some corner cases,
 *                    it's desirable for the script to remain in the page. However,
 *                    even for asynchronous functionality it's usually not necessary, as
 *                    the context containing the code will be kept with any references
 *                    (e.g. the reference to a callback function).
 *    id            If this is a non-blank string, it is used as the ID for the <script>
 *    All additional parameters   are passed to the function executing in the page.
 *                    This is done by converting them to JavaScript code-text and back.
 *                    All such parameters must be Object, Array, functions, RegExp,
 *                    Date, and/or other primitives (Boolean, null, undefined, Number,
 *                    String, but not Symbol). Circular references are not supported.
 *                    If you need to communicate DOM elements, you will need to
 *                    pass selectors, or other descriptors of them (e.g. temporarily
 *                    assign them a unique class), or otherwise communicate them to the
 *                    script (e.g. you could dispatch a custom event once the script is
 *                    inserted into the page context).
 */
function executeInPage(functionToRunInPage, leaveInPage, id) {
    //Execute a function in the page context.
    // Any additional arguments passed to this function are passed into the page to the
    // functionToRunInPage.
    // Such arguments must be JSON-ifiable (also Date, Function, and RegExp) (prototypes
    // are not copied).
    // Using () => doesn't set arguments, so can't use it to define this function.
    // This has to be done without jQuery, as jQuery creates the script
    // within this context, not the page context, which results in
    // permission denied to run the function.
    function convertToText(args) {
        //This uses the fact that the arguments are converted to text which is
        //  interpreted within a <script>. That means we can create other types of
        //  objects by recreating their normal JavaScript representation.
        //  It's actually easier to do this without JSON.strigify() for the whole
        //  Object/Array.
        var asText = '';
        var level = 0;
        function lineSeparator(adj, isntLast) {
            level += adj - ((typeof isntLast === 'undefined' || isntLast) ? 0 : 1);
            asText += (isntLast ? ',' : '') +'\n'+ (new Array(level * 2 + 1)).join('');
        }
        function recurseObject(obj) {
            if (Array.isArray(obj)) {
                asText += '[';
                lineSeparator(1);
                obj.forEach(function(value, index, array) {
                    recurseObject(value);
                    lineSeparator(0, index !== array.length - 1);
                });
                asText += ']';
            } else if (obj === null) {
                asText +='null';
            //undefined
            } else if (obj === void(0)) {
                asText +='void(0)';
            //Special cases for Number
            } else if (Number.isNaN(obj)) {
                asText +='Number.NaN';
            } else if (obj === 1/0) {
                asText +='1/0';
            } else if (obj === 1/-0) {
                asText +='1/-0';
            //function
            } else if (obj instanceof RegExp || typeof obj === 'function') {
                asText +=  obj.toString();
            } else if (obj instanceof Date) {
                asText += 'new Date("' + obj.toJSON() + '")';
            } else if (typeof obj === 'object') {
                asText += '{';
                lineSeparator(1);
                Object.keys(obj).forEach(function(prop, index, array) {
                    asText += JSON.stringify(prop) + ': ';
                    recurseObject(obj[prop]);
                    lineSeparator(0, index !== array.length - 1);
                });
                asText += '}';
            } else if (['boolean', 'number', 'string'].indexOf(typeof obj) > -1) {
                asText += JSON.stringify(obj);
            } else {
                console.log('Didn\'t handle: typeof obj:', typeof obj, '::  obj:', obj);
            }
        }
        recurseObject(args);
        return asText;
    }
    var newScript = document.createElement('script');
    if(typeof id === 'string' && id) {
        newScript.id = id;
    }
    var args = [];
    //using .slice(), or other Array methods, on arguments prevents optimization
    for(var index=3;index<arguments.length;index++){
        args.push(arguments[index]);
    }
    newScript.textContent = '(' + functionToRunInPage.toString() + ').apply(null,'
                            + convertToText(args) + ");";
    (document.head || document.documentElement).appendChild(newScript);
    if(!leaveInPage) {
        //Synchronous scripts are executed immediately and can be immediately removed.
        //Scripts with asynchronous functionality of any type must remain in the page
        //  until complete.
        document.head.removeChild(newScript);
    }
    return newScript;
};
function logInPageContext(arg0,arg1,arg2,arg3){
    console.log('arg0:', arg0);
    console.log('arg1:', arg1);
    console.log('arg2:', arg2);
    console.log('arg3:', arg3);
}

executeInPage(logInPageContext, false, '', 'This', 'is', 'a', 'test');


/* executeInPage takes a function defined in this context, converts it to a string
 *  and inserts it into the page context inside a <script>. It is placed in an IIFE and
 *  passed all of the additional parameters passed to executeInPage.
 *  Parameters:
 *    func          The function which you desire to execute in the page. 
 *    leaveInPage   If this does not evaluate to a truthy value, then the <script> is
 *                    immediately removed from the page after insertion. Immediately
 *                    removing the script can normally be done. In some corner cases,
 *                    it's desirable for the script to remain in the page. However,
 *                    even for asynchronous functionality it's usually not necessary, as
 *                    the context containing the code will be kept with any references
 *                    (e.g. the reference to a callback function).
 *    id            If this is a non-blank string, it is used as the ID for the <script>
 *    All additional parameters   are passed to the function executing in the page.
 *                    This is done by converting them to JavaScript code-text and back.
 *                    All such parameters must be Object, Array, functions, RegExp,
 *                    Date, and/or other primitives (Boolean, null, undefined, Number,
 *                    String, but not Symbol). Circular references are not supported.
 *                    If you need to communicate DOM elements, you will need to
 *                    pass selectors, or other descriptors of them (e.g. temporarily
 *                    assign them a unique class), or otherwise communicate them to the
 *                    script (e.g. you could dispatch a custom event once the script is
 *                    inserted into the page context).
 */
function executeInPage(functionToRunInPage, leaveInPage, id) {
    //Execute a function in the page context.
    // Any additional arguments passed to this function are passed into the page to the
    // functionToRunInPage.
    // Such arguments must be JSON-ifiable (also Date, Function, and RegExp) (prototypes
    // are not copied).
    // Using () => doesn't set arguments, so can't use it to define this function.
    // This has to be done without jQuery, as jQuery creates the script
    // within this context, not the page context, which results in
    // permission denied to run the function.
    function convertToText(args) {
        //This uses the fact that the arguments are converted to text which is
        //  interpreted within a <script>. That means we can create other types of
        //  objects by recreating their normal JavaScript representation.
        //  It's actually easier to do this without JSON.strigify() for the whole
        //  Object/Array.
        var asText = '';
        var level = 0;
        function lineSeparator(adj, isntLast) {
            level += adj - ((typeof isntLast === 'undefined' || isntLast) ? 0 : 1);
            asText += (isntLast ? ',' : '') +'\n'+ (new Array(level * 2 + 1)).join('');
        }
        function recurseObject(obj) {
            if (Array.isArray(obj)) {
                asText += '[';
                lineSeparator(1);
                obj.forEach(function(value, index, array) {
                    recurseObject(value);
                    lineSeparator(0, index !== array.length - 1);
                });
                asText += ']';
            } else if (obj === null) {
                asText +='null';
            //undefined
            } else if (obj === void(0)) {
                asText +='void(0)';
            //Special cases for Number
            } else if (Number.isNaN(obj)) {
                asText +='Number.NaN';
            } else if (obj === 1/0) {
                asText +='1/0';
            } else if (obj === 1/-0) {
                asText +='1/-0';
            //function
            } else if (obj instanceof RegExp || typeof obj === 'function') {
                asText +=  obj.toString();
            } else if (obj instanceof Date) {
                asText += 'new Date("' + obj.toJSON() + '")';
            } else if (typeof obj === 'object') {
                asText += '{';
                lineSeparator(1);
                Object.keys(obj).forEach(function(prop, index, array) {
                    asText += JSON.stringify(prop) + ': ';
                    recurseObject(obj[prop]);
                    lineSeparator(0, index !== array.length - 1);
                });
                asText += '}';
            } else if (['boolean', 'number', 'string'].indexOf(typeof obj) > -1) {
                asText += JSON.stringify(obj);
            } else {
                console.log('Didn\'t handle: typeof obj:', typeof obj, '::  obj:', obj);
            }
        }
        recurseObject(args);
        return asText;
    }
    var newScript = document.createElement('script');
    if(typeof id === 'string' && id) {
        newScript.id = id;
    }
    var args = [];
    //using .slice(), or other Array methods, on arguments prevents optimization
    for(var index=3;index<arguments.length;index++){
        args.push(arguments[index]);
    }
    newScript.textContent = '(' + functionToRunInPage.toString() + ').apply(null,'
                            + convertToText(args) + ");";
    (document.head || document.documentElement).appendChild(newScript);
    if(!leaveInPage) {
        //Synchronous scripts are executed immediately and can be immediately removed.
        //Scripts with asynchronous functionality of any type must remain in the page
        //  until complete.
        document.head.removeChild(newScript);
    }
    return newScript;
};

thanks for the answer ... I just want to know how can I access controls that are in background/popup page of extension??

I'm not sure of the context of your question. Are you wanting to access controls in the background script and/or popup from the content script?The only way to communicate between a content script and a background page is through messaging. You should probably read Content Scripts: Communicating with background scripts

I mean the controls that are in popup.html (where I define UI for plugin). I will put the ID of first task in textBox and on button click start the task and button with ID is the start point.

@Hitin, Accessing controls in the popup is done through JavaScript in a separate file and included in the popup HTML with a <script>. Google's Options page includes HTML and JavaScript that works equally well as a popup (just add a browser_action with "default_popup": "options.html").

jquery - Calling webpage JavaScript methods from browser extension - S...

javascript jquery cross-domain browser-plugin firefox-webextensions
Rectangle 27 5

JavaScript code needs some time to execute. Try to have a delay between setting the page content and calling render.

Ariya Thank you for the phantomjs! And good luck with a new versions :))

node.js - page.set('content') dosen't work with dynamic content in pha...

node.js phantomjs
Rectangle 27 2

The javascript interpreter runs all code single-threaded in a big event loop; your calling setTimeout enqueues the callback as another event to be executed as soon as the current code is done (and other code that may have been enqueued previously).

So the interpreter executes it like this:

get and execute next event
  calling your global <script> code
    calling console.log('one');
    calling setTimeout(func);
    calling console.log('three');
  returning from your global <script> code
get and execute next event*
  calling setTimeout callback
    calling console.log('two');
  returning from setTimeout callback

(*): There may be other callbacks enqueued to be called between these two.

javascript - Why there is a delay even though setTimeout is set to 0 d...

javascript
Rectangle 27 2

The javascript interpreter runs all code single-threaded in a big event loop; your calling setTimeout enqueues the callback as another event to be executed as soon as the current code is done (and other code that may have been enqueued previously).

So the interpreter executes it like this:

get and execute next event
  calling your global <script> code
    calling console.log('one');
    calling setTimeout(func);
    calling console.log('three');
  returning from your global <script> code
get and execute next event*
  calling setTimeout callback
    calling console.log('two');
  returning from setTimeout callback

(*): There may be other callbacks enqueued to be called between these two.

javascript - Why there is a delay even though setTimeout is set to 0 d...

javascript
Rectangle 27 3

I just solved my problem: when all document is loaded, $(function(){}) will not work again, so calling a script which uses $(function(){}) will no get run. I removed it from all my secondary-called scripts and now all works perfectly!

javascript - Using $.getScript (jquery): code is not executed - Stack ...

javascript php jquery ajax getscript
Rectangle 27 1

Look at your Javascript-to-Objective-C code and if you are executing/calling javascript code make sure that script does not invoke new calls to Objective-C.

Javascript >> Objective-C

Objective-C >> Javascript
Objective-C >> Javascript >> Objective-C

Solution is specific for your project code. But easiest would be to wrap all Javascript in setTimeout() to schedule execution in Javascript thread. Here is simple example, your Objective-C code needs to execute this script:

storeUserPhoneNumber("011 123 4567");

Crash will happen if storeUserPhoneNumber function calls back to Objective-C code (directly or indirectly) in its body. To fix this just wrap code in setTimeout like this:

setTimeout(function() {
    storeUserPhoneNumber("011 123 4567");
}, 0);

ios - Unreproducible webcore crashes - Stack Overflow

ios objective-c ipad uiwebview crash
Rectangle 27 15

Functions don't exist as part of the DOM; instead, they exist within an execution environment that includes the DOM. Content scripts (including scripts run with executeScript) and actual web pages share the same DOM, but have separate execution environments. So calling window.alert = function() {} only rewrites window.alert within your content script's execution environment, not in the actual page's one.

The typical way to reach the execution environment of the actual page is to inject a <script> tag into the DOM. This can be done in several ways. One method is to white-list a script in web_accessible_resource, and insert the <script> element referring to this script in the document. The required absolute URL can be obtained via chrome.extension.getURL.

var s = document.createElement("script");
s.src = chrome.extension.getURL("script_in_extension.js");
(document.head||document.documentElement).appendChild(s);

Make sure that the script is configured to "run_at": "document_start", so that the overwrite takes place before any of the page's functions are loaded.

Note: Your action can easily be undone by the page:

window.alert = function(){ /*...*/ }; // Your overwrite
delete window.alert;                  // Run from the page/console/...
window.alert('Test?');                // Displays alert box.

If it's critical that the overwritten function cannot be removed, use Object.defineProperty to define an immutable method. For more details, see Stop a function from execute with Chrome extension.

@RobW defineProperty is a very good note (but should it read "replace the property", or am I not quite following you?). I didn't mention the run_at property since they OP only asked about using executeScript, but it's definitely useful and relevant in almost all cases. Looks good, thanks.

@RobW @apsillers, Re "..overwrite.."; you'll also need to async=false if you're using src=. In any case, I've got little faith that its guaranteed to run at the start, even while the docs write that its before any other script is run. Does someone have a link to that portion of source code? Also, aside from <manifest executescript document_start> there's <onCommitted executescript document_start>.

ftp://speedtest.tele2.net
www.w3fools.com
https://en.wikipedia.org/wiki/Main_Page

google chrome - Is it possible to inject a javascript code that OVERRI...

google-chrome google-chrome-extension
Rectangle 27 0

You cannot do that in IE, you've discovered. You need to make sure that any objects you pass between frames are native things like strings. Even "Date" instances have caused me problems, though that was on obscure versions of Windows 2000 back in the day.

By "freed script" what IE means is that your the page context where an object was "born" has been overwritten by a new page.

So there is no way to override a function in a different frame in IE? What's strange is that even if I use variables in "myFrame" to hold the function pointers, I still get this error.

Yes, you can, but the problem happens when you have a "stale" object that was born in another page. As soon as your code tries to touch it, IE realizes that its prototype object (and etc.) are gone. It's just the way that the JScript mechanism seems to work.

What in my code represents the "stale" object? How can I modify this code to prevent this from happening?

Well it probably has something to do with things passed back and forth between the pages. Or, perhaps, if you override the function in the other frame and then the frame from which you do that is overwritten. Now, if your frames are completely static and they're never reloaded with new pages from the server, then that's a new one on me.

javascript - Can't execute code from a freed script - Stack Overflow

javascript override
Rectangle 27 0

If your javascript code is in a javascript file, PHP does not process that so you cannot execute PHP code there.

So you can either put the javascript code directly into the PHP page

<script type="text/javascript">
function someFunction()
{
    document.getElementById('exp').innerHTML = "<?php echo $doc ?>";
}
</script>

or you can do the follow:

<script type="text/javascript">
var doc = "<?php echo $doc ?>";
</script>

Then in the javascript file do:

function someFunction()
{
    document.getElementById('exp').innerHTML = doc;
}

This seems like it's a really good answer but for some reason I'm not getting it right this way. The path is correct and I'm sure the variable has it's content because when I do "echo $doc" on the php part, it appears on the screen. But I'm not getting to achieve how to link that variable and put it's content inside javascript the right way.

document.getElementById('exp').innerHTML = "<?php echo addslashes($doc) ?>";

javascript not calling php variable - Stack Overflow

javascript php html variables
Rectangle 27 0

Beginning in IE9 we began receiving this error when calling .getTime() on a Date object stored in an Array within another Object. The solution was to make sure it was a Date before calling Date methods:

yes. IE9 will mangle types. You may also get it with arrays. You can do Array.prototype.slice.call(data) if you want. Sometimes it will throw this error, sometimes it will throw E_UKNOWN ... it's usually caused by a spurious "delete" improperly invoked and unfortunately has nothing to do with the child/parent issue; it's the browser going nutso over something and giving you a red herring.

javascript - What causes the error "Can't execute code from a freed sc...

javascript internet-explorer
Rectangle 27 0

This isn't really an answer, but more an example of where this precisely happens.

We have frame A and frame B (this wasn't my idea, but I have to live with it). Frame A never changes, Frame B changes constantly. We cannot apply code changes directly into frame A, so (per the vendor's instructions) we can only run JavaScript in frame B - the exact frame that keeps changing.

We have a piece of JavaScript that needs to run every 5 seconds, so the JavaScript in frame B create a new script tag and inserts into into the head section of frame B. The setInterval exists in this new scripts (the one injected), as well as the function to invoke. Even though the injected JavaScript is technically loaded by frame A (since it now contains the script tag), once frame B changes, the function is no longer accessible by the setInterval.

javascript - What causes the error "Can't execute code from a freed sc...

javascript internet-explorer
Rectangle 27 0

I got this error in IE9 within a page that eventually opens an iFrame. As long as the iFrame wasn't open, I could use localStorage. Once the iFrame was opened and closed, I wasn't able to use the localStorage anymore because of this error. To fix it, I had to add this code to in the Javascript that was inside the iFrame and also using the localStorage.

javascript - What causes the error "Can't execute code from a freed sc...

javascript internet-explorer
Rectangle 27 0

It doesn't have much to do with Python, really. Your javascript code is executed on the client's brower, and all it can do is issuing HTTP requests (synchronous or asynchronous). At this point which webserver / technology / language is used to handle the HTTP request is totally irrelevant. So, from the client javascript code POV, you are not "calling a Python function", you are sending an HTTP request and handling the HTTP response.

If your web host doesn't let you run django (or any wsgi-compliant script) then you'll probably have to either use plain CGI (warning: very primitive techno) or migrate to PHP (no comment). Or find another hosting that doesn't live in the past ;)

That would have been my last option, I don't want to switch to php, I wanted to learn something new on the open source sphere, and choosed python and django, which was surprising good. And then I realized my hosting plan didn't had django neither flask...

Call python FUNCTION from javascript - Stack Overflow

javascript python angularjs client-server
Rectangle 27 0

All server inline code such as <%=setDone(123)%> is executed during generation of the page, and it's position in JavaScript is merely because you placed it there.

You can use inline code to pass server side data to JavaScript in this fashion.

If you want JavaScript to execute server side code, you can use several techniques. As well as WebMethods described by mattyTommo you can put a value in a input box, and then call a button click for a server side button and have the server side code read the content of the input box.

c# 4.0 - error in calling code behind C# method from javascript functi...

javascript c#-4.0 code-behind
Rectangle 27 0

Because calling document.write implicity calls document.open, which clears the document on which it has been called:

If a document exists in the target, this method clears it

After the call to document.write, the element you're trying to get a reference to no longer exists in the DOM, and an error is thrown. If you look in the error console it should be something along the lines of the following:

TypeError: Cannot read property 'txt1' of undefined

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

javascript - Why is code after document.write() not executed? - Stack ...

javascript
Rectangle 27 0

I bet your newRoutesContainerRouteRS includes complex objects and as stated there - extend only works with simple objects

Thank you; that looks like its probably the issue. The question becomes, how does one get around that? Someone posted a comment on that question linking to oranlooney.com/deep-copy-javascript which looked like it might help, but I've been unable to get it working correctly as of yet.

Thanks John; that's where I found the aforementioned link. I'll try to spend some more time with it in the coming week or two to see if I can work out a good, simple solution. If I can I'll post it here.

javascript - Deep copy to avoid "Can't execute code from a freed scrip...

javascript jquery internet-explorer-8
Rectangle 27 0

This cannot be done in the way that you want it to be done. If you plan to execute something like MsgBox or MessageBox.Show in your server's code behind you will be out of luck. The reason you cannot do this is because a modal popup box would appear on the server and would block the process until someone somewhere on that server clicks OK or Cancel, or whatever button. What you need is to do this on the client side by calling javascript alert() function.

vb.net - Cannot display message box on dev server in asp.net - Stack O...

asp.net vb.net messagebox
Rectangle 27 0

The solution - be sure to place all META statements BEFORE any script statements.

Dit you test it yourself? Or is this copied from another website? I have no meta tags at all and I still get this error

javascript - Can't execute code from a freed script - IE6 IE7 IE8 IE9 ...

javascript internet-explorer-8 internet-explorer-7 internet-explorer-6 internet-explorer-9
Rectangle 27 0

You cannot simply mix PHP and JavaScript. The former is executed on the server, the latter on the client, namely in the user's browser. In order to hand a value from PHP to JavaScript you need to output JavaScript code via PHP or do a AJAX-Request to a PHP-Script, as you tried. When using AJAX, it is the easiest solutions to have PHP script that returns a JSON string. When calling this script using $.get() the result will be stored in a JavaScript variable and you can access all the values from there.

Take a moment and a deep breath...and then start thinking about your scopes again.

javascript - Passing value to PHP variable inside script - Stack Overf...

php javascript jquery
Rectangle 27 0

The problem is the way you are calling setInterval, you need to pass a function, where as you are currently passing the result of a function, which won't do anything useful.

The correct way to pass a function (rather than the result of a function) would be as follows:

setInterval(change, 1000);

However, this doesn't allow for specifying your parameters. To do that you can use an anonymous function and call your function (with parameters) from within that:

setInterval(function() { change('#_1x1_1_1'); }, 1000);

As you have quite a few squares, I would suggest you make use of the class selector and loop them. For example:

function change(element) {
    var ranColor = Math.floor(color.length * Math.random());
    element.css('background-color', color[ranColor]);
}

$.each($('.squares'), function (index, element) {
    setInterval(function () {
        change($(element));
    }, 1000);
});

big thanks! this worked perfectly! thanks to the other users i will check them out too! :)

how would i do a clearInterval for this thing? i made a button which is supposed to call a function to stop changing the colors but its not working..

@StefanDjurcic: As you probably know, setInterval returns an id for the interval. So what you can do is push each one to a global array. Then when you need to stop, loop the array and call clearInterval for each id. Here is an example

javascript - Cant get jquery code to execute every second..? - Stack O...

javascript jquery