5

I am having trouble to inject react element via chrome extension. Although it may be duplicated, i have already read some questions in terms of injecting react element via chrome extension and tried a various methods to inject react element. but it is still not working.

READ1

READ2

READ3

Following my code

manifest.json

{
    "manifest_version": 2,
    "name": "__MSG_name__",
    "version": "1.0.0",
    "description": "__MSG_description__",
    "author": "Seokjun Hong",
    "default_locale": "en",
    "browser_action": {
        "default_title": "__MSG_name__"
    },
    "web_accessible_resources": [
        "js/jquery-2.2.3.min.js",
        "html/emoji_box.html",
        "js/vendor/browser.min.js",
        "js/vendor/react.min.js",
        "js/vendor/react-dom.min.js",
        "js/vendor/react-with-addons.min.js",
        "js/test.js"
    ],
    "content_scripts": [{
        "matches": [
            "https://github.com/*",
            "https://gist.github.com/*"
        ],
        "js": [
            "js/jquery-2.2.3.min.js",
            "js/content_script.js",
            "js/semantic.min.js",
            "js/test.js"
        ],
        "css": [
            "css/semantic.min.css"
        ],
        "run_at": "document_idle",
        "all_frames": false
    }]
}

test.js (react element)

/** @jsx React.DOM */
var Counter = React.createClass({
    getInitialState: function () {
        return { count: 0 };
    },
    handleClick: function () {
        this.setState({
            count: this.state.count + 1,
        });
    },
    render: function () {
        return (
            <button onClick={this.handleClick}>
                Click me! Number of clicks: {this.state.count}
            </button>
        );
    }
});
ReactDOM.render(
    <Counter />,
    document.getElementsByClassName('timeline-comment')[0]
);

content_script.js

(function() {
    //append react script, following trial
})();

I have tried to inject react script into content.

TRIAL1: Injecting script tag using createElement

// Adds the react.jsx
var jsx = document.createElement('script');
jsx.src = chrome.extension.getURL('js/test.js');
jsx.type="text/babel";
jsx.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(jsx);

I also tried following code

$(document.head).append('<script src="' + chrome.extension.getURL('js/test.js') + '" type="text/babel"></script>')

TRIAL2: Loading script using getScript of jQuery

$.getScript(chrome.extension.getURL('js/test.js'), function(){
});

In this case, I also tried to load all script to execute react code, e.g., browser.min.js, react.min.js, react-dom.min.js.

Various trial returns errors, e.g., Unexpected Token '<' or script not loading.

Everything is not working. i don't know how to inject react element.

Community
  • 1
  • 1
se0kjun
  • 550
  • 4
  • 14

1 Answers1

3

The easiest way to achieve that would be using manifest.json injection rather Programming injection like chrome.tabs.executeScript or inserting script tag.

A sample manifest.json as follows,

manifest.json

{
    "manifest_version": 2,
    "name": "__MSG_name__",
    "version": "1.0.0",
    "description": "__MSG_description__",
    "author": "Seokjun Hong",
    "browser_action": {
        "default_title": "__MSG_name__"
    },
    "content_scripts": [
        {
            "matches": [
                "<all_urls>"
            ],
            "js": [
                "react.js",
                "react-dom.js",
                "react-with-addons.js",
                "test.js"
            ],
            "run_at": "document_idle",
            "all_frames": false
        }
    ]
}

test.js

var HelloMessage = React.createClass({
  displayName: "HelloMessage",

  render: function render() {
    return React.createElement(
      "div",
      null,
      "Hello ",
      this.props.name
    );
   }
});

ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), document.body);

Please be aware in this case you would need to use compiled js rather than JSX.

And if you want to do Programming injection, please make sure all react related js is injected before you inject your test.js. As for your injecting code, you need to use the same way to inject react.js and etc before injecting test.js, or just include those files in content_scripts field.

Haibara Ai
  • 10,703
  • 2
  • 31
  • 47
  • Thanks for your answer, but still not working. I follow your manifest.json and load chrome-extension. Error, `Uncaught SyntaxError: Unexpected token <`, occurs in `test.js`. – se0kjun May 12 '16 at 07:40
  • @se0kjun, updated, in this case you would need to use compiled js rather than jsx. – Haibara Ai May 12 '16 at 07:50
  • 1
    If i use `jsx`, Should i use a bundler such as webpack or gulp? – se0kjun May 12 '16 at 08:03
  • @se0kjun, if you want `manifest.json` injection, then you should pre-compile jsx; if using programming injection, then just make sure all the scripts are injected, and I have not tested, but maybe you would need to change `content_security_policy` if react has done something violating the default CSP. – Haibara Ai May 12 '16 at 08:09