0

I would like to be able to expose a function-scoped variable that is part of a website's (not mine) javascript.

Here's a simplified example:

function addHooks(e, t, n, i) {
    var props = {                    // Would like to expose this
        update: function() { ... },
        remove: function() { ... },
        find: function() { ... },
    };
    ...
}

In the above example, I would like to expose the props variable so that my webextension can then access this to modify the behavior of the website. Please note, that the website that serves this JS file isn't under my control and thus, I cannot simply modify the source file to export this variable. However, I'm fully open to modifying the final code that the browser runs (I just don't know how to). The javascript file containing the addHooks function appears to be added dynamically via XHR.

Although I have no idea on how to accomplish this programmatically, I have had some success setting a breakpoint and then issuing window.siteController = props in the browser's developer console. Unfortunately, manual user-intervention is not something I can package and distribute.

One method that I have been toying with is the idea of making an AJAX request for the JS file, modifying its script contents and appending it to the page.

Is there a canonical, programmatic way in which a function-scoped variable can be exposed?

Guru Prasad
  • 4,053
  • 2
  • 25
  • 43
  • The javascript source isn't mine and is thus not available for me to modify at the source level. – Guru Prasad Dec 15 '16 at 07:08
  • you can't access a variable outside its scope... – Punit Dec 15 '16 at 07:12
  • then it is not possible access that property, check whether is there any function to access that property outside – Azad Dec 15 '16 at 07:12
  • So your question is, can I modify the behavior of a function, without changing the function. No. –  Dec 15 '16 at 07:15
  • It *should not* be possible, and seems so if you look around about this topic. However someone provided some hacky solution which you might be interested in: http://stackoverflow.com/a/25473571/3132718 – Al.G. Dec 15 '16 at 07:16
  • @GuruPrasad, you are writing an extension. Actually changing the website's code *is* an option. – Makyen Dec 15 '16 at 07:16
  • @torazaburo: I don't see where I mentioned that the function must not be modified. I simply don't know _how_ to modify the function – Guru Prasad Dec 15 '16 at 07:17
  • @GuruPrasad in your first comment you said you couldn't modify the source code. But the easiest way would be to just `return props;` – Al.G. Dec 15 '16 at 07:20
  • What are you looking for in an answer here? You appear to already understand that you have to change the code in order to expose the variable. Are you just looking for someone to say "Yes, you have to change the code"? Are you looking for someone to tell you how to accomplish that? If so, we need quite a bit more information (a *complete* [MCVE]). The way you have worded this Question, it sounds like you are dismissing the possibility of changing the code while asking for another way to expose the variable. The canonical way to expose the variable is to change the code. – Makyen Dec 15 '16 at 07:58
  • I don't know enough JS to know if what I want is achievable and how to achieve what it. I am fully open to modifying the source. However, as some people have suggested, I *cannot* change the _file_ since I'm not the one hosting it. Having said that, I'm fully open to modifying the `XHR` response to achieve my needs. I stated one potentially viable solution, but I don't know how one would implement it. I also don't know if it can actually work. Perhaps I should understand the problem better so I can explain it better. – Guru Prasad Dec 15 '16 at 08:06
  • @GuruPrasad, A significant portion of the issue with the question is that we really don't have enough information to provide concrete, "this will work" answers. What will be needed in order to accomplish what you desire will depend on how code is handled on the page. It may be something as simple as providing a different version of the function inserted as a page script. It may require effectively nullifying the XHR request, fetching the code yourself, modifying it and then inserting it into the page. Without substantially more detail, all we can Answer with are generalities and possibilities. – Makyen Dec 15 '16 at 08:22
  • @GuruPrasad, BTW: If you want a specific person to be notified of your comment, you need to include their ID in your comment with an `@` in front of it. For instance, for me it would be `@Makyen`. If you do this as the first thing in your comment, the system will provide auto-complete suggestions from those who have already posted comments on that answer/question. The original poster of the answer/question on which you are commenting will always be notified. This [meta post](http://meta.stackexchange.com/a/43020/271271) has more information. – Makyen Dec 15 '16 at 08:31

2 Answers2

-1

EDIT: Thanks to Makyen who pointed out my error. Apparently you might be able to do it if you re-define the function in a page script and insert it as a script element. (See the comment for two references).

Just be sure that your <script> element is inserted after the original definition and then you can either return props at the end of the function, or use this.props and use the function either as a constructor or using thecallfunction, passing an object that will get the props property added.


Old answer ( __ wrong__ apparently)

Short answer: you can't.

Full explanation: if you can't change the code of the function and you can only use the function (call it) you cannot alter its variable's scope (and good thing you can't, too. There's a reason why the variable was limited to its current scope).

And you can't change the website's JavaScript. As a Firefox or Chrome extension (and possibly the same fires to other browsers I'm not sure) you can't even access the function (let alone it's inner variables). I mean to say you can't even call it from the extension of it's in the website's code.

content scripts cannot see JavaScript variables defined by page scripts More info and source

Firefox/Chrome runs your JavaScript code in a parallel environment, isolated from the website's environment. This is of course for security reasons. It also helps for you to be able to develop without knowing the exact inner workings of each website your code might be injected into, as you don't need to bother regarding naming conflicts (which would be impossible if it weren't for the separation environments). The only thing you do have access to is the DOM, through which you can gather information, alter the website and even talk with the website in some cases (the website should follow a protocol you decide upon as well).

et_l
  • 1,868
  • 17
  • 29
  • Both Firefox and Chrome have similar capabilities in this regard. An extension has access to quite a bit more than just the DOM. You have limited your thinking to a narrow view of an extension's capabilities. An extension *can* call page functions, you just have to do so from a page script. There are multiple Questions/answers on doing so (e.g. [this one](http://stackoverflow.com/a/40320909/3773011) and [this one](http://stackoverflow.com/a/40572286/3773011), both from just the last month and a half). – Makyen Dec 15 '16 at 07:51
-1

if it's the props object variable that you want exposed, you could return he entire object from the functin, like in closures. Or , you could, simple declare a the enclosing function as a constructor function, set props as this.props and then, invoke the same function elsewhere, using the new keyword. Let me know if this helps

Soham Bhaumik
  • 211
  • 2
  • 15
  • How would i change it to achieve this? The script is being added to the page via `XHR`. As I've already mentioned, the script source code is not under my control. – Guru Prasad Dec 15 '16 at 07:32
  • Then only possible if you could change props to this.props and retrieve this in the other functon – Soham Bhaumik Dec 15 '16 at 10:04