0

I want to insert a script in Firefox Add-on SDK content script added via page-mod. So, when user goes to page XXX, he gets a page with the inserted script. But, when trying to insert this at the top of HEAD, I got an error that the 1st Node child is not an object.

My content script code with which I insert the <script> is:

script='<script>var d=new Date(2012,2,24); window.Date=function () {return d;}</script>';

var head = document.getElementsByTagName("head")[0];
head.insertBefore(script, head.firstChild);

What's with it?

Makyen
  • 31,849
  • 12
  • 86
  • 121
user2543953
  • 123
  • 1
  • 3
  • 11
  • Please [edit] your question to provide a *complete* [mcve]. That means all the files needed for a minimal add-on. What is actually happening depends on significantly more than the 3 lines of code you have shown (although, there are obvious issues). – Makyen Aug 13 '16 at 15:20
  • Please provide the *exact* error text you see in either the console, or in the shell from which you run `jpm run`. – Makyen Aug 13 '16 at 15:41
  • 1
    Note that injecting ` – the8472 Aug 13 '16 at 20:39
  • Thanks! It works. About untrusted contents is specially of interest. But here we can check the page contents. Good theme to think and talk. – user2543953 Aug 14 '16 at 11:49

1 Answers1

4

You have not provided a Minimal, Complete, and Verifiable Example. Thus, this answer is based just on the code you have provided.

Issue with how you are using insertBefore():

The first issue I noticed is that you are providing a string as the first argument to insertBefore() when that argument needs to be a node object.

However, you state the error you are getting is "1st Node child is not an object". This does not match what I would expect from an error based on the code provided. When I put your code in a page-mod content script, the error I got was:

console.error: testpagemodinsertBefore:
Object
    - _errorType = TypeError
    - message = Argument 1 of Node.insertBefore is not an object.
    - fileName = resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/loader/sandbox.js -> resource://testpagemodinsertbefore/data/contentScript.js
    - lineNumber = 26
    - stack = @resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/loader/sandbox.js -> resource://testpagemodinsertbefore/data/contentScript.js:26:1|
    - name = TypeError

This is the error which I would expect from the code in the question. Thus, you have either not posted the code which is producing the error you have stated, or you have inaccurately reported the error which you saw in the console. In the future, please be exact in what you are reporting. Being more verbose is better than leaving things out.

Inserting HTML text:

Your code:

script='<script>var d=new Date(2012,2,24); window.Date=function () {return d;}</script>';

defines some HTML text which you are trying to insert into the DOM. If you want to insert HTML text instead of inserting nodes, one way for you to do so is to use insertAdjacentHTML(). One way you could do this in your code is:

head.insertAdjacentHTML('afterbegin',script);

This works well for most HTML. But, does not result in the contents of the <script> tag being executed/evaluated. This is for security reasons. It is much easier for an attacker to get arbitrary text inserted into the DOM than it is for them to insert actual nodes/elements. The HTML specification specifies that a tag inserted inserted as text will not be executed.

Inserting a <script> tag that is evaluated and executed:

We can do this by creating a <script> element containing the script text desired, then inserting that element into the DOM.

For your code that would look something like:

//Get the first <head> element
let head = document.getElementsByTagName("head")[0];

//The script text desired
let scriptText='var d=new Date(2012,2,24); window.Date=function () {return d;};';

//Add an alert for testing (\n is not needed. But, is more readable when inspecting DOM.)
scriptText = 'window.alert("In inserted script");\n' + scriptText;

//Create a <script> element
let scriptEl = document.createElement( 'script' );
//That is JavaScript
scriptEl.type = 'text/javascript'; 
//Add the script text
scriptEl.textContent = scriptText;
//Insert it as the firstChild of <head>
head.insertBefore( scriptEl, head.firstChild );

Further reading:

You appear to be desire to interact with page scripts using your content script. I suggest that you read the MDN page "Interacting with page scripts".

Community
  • 1
  • 1
Makyen
  • 31,849
  • 12
  • 86
  • 121