1

I'm trying to use a Chrome Extension as a complimentary tool for the web app I'm developing.

I used chrome.tab.executeScript to manipulate the DOM of the web app and append a button inside a DIV.

chrome.tabs.executeScript({

    code: 'var e =  document.createElement("div");' +
              'e.innerHTML = "' + 
              '<button ng-click="myfnc()"></button>' +
              '";' +    
              'document.getElementsByTagName("body").appendChild(e);'

});

The button is added/appended as expected.

<body>
    <div>
       <button ng-click="myfnc()"></button>
    </div>
</body>

The button has ng-click attribute that points to function on the web app. The function is just a simple alert call.

myfnc():

alert('Hello!');

However, when I click on the button nothing happens. Do you have any idea why? Can injected html coming from Google Chrome Extension interact directly with the web page's code?

sdgluck
  • 24,894
  • 8
  • 75
  • 90
jimx
  • 57
  • 9

1 Answers1

2

Creating an element with the attribute ng-click does not inform Angular that the element exists within the page, as parsing of the document occurs once during bootstrap. You therefore have an element which exists 'outside' of any Angular scope, meaning the attribute ng-click just exists and has not caused the corresponding directive (ngClick) to be invoked.

Providing of course that the page has Angular, you will want to use the $compile service along with the desired $scope to compile the element after it has been inserted into the page.

A comprehensive solution is outside of the scope of your question. (Why does nothing happen when the button is clicked?) If you want to read more about using injected code with Angular, read up on:

The steps you want to take are something like...

  1. Get the $scope you want to insert the element within:

    var angular = document.querySelector('body');
    var scope = angular.element(angular).scope();
    
  2. Insert the new element into the page:

    var newElem = angular.element('div');
    angular.append(newElem);
    
  3. $compile the element with this $scope:

    $compile(newElem)(scope);
    

More information on dynamically creating Angular elements can be found in the answer to this question.

sdgluck
  • 24,894
  • 8
  • 75
  • 90
  • Thank you so much for pointing me in the right direction. I'll try to learn more about this. In item 2 is it `angular.append(ngElem);` or `angular.append(newElem);`? – jimx Jan 07 '16 at 10:34
  • So what i have to do is get the `$scope` where I want to put the button; append the element and use `$compile` to _render_ it on the page. That really makes sense. The only problem with this is `chrome.tabs.executeScript` does not have access to the `angularjs` file and other javascripts on the webpage. It runs on an _isolated world_, thus your suggestion will have this error `Uncaught ReferenceError: angular is not defined` @sdgluck – jimx Jan 07 '16 at 10:59
  • @jimx Inject a ` – sdgluck Jan 07 '16 at 11:01
  • That came to mind! :D Yes that might actually work. I'll use `chrome.tabs.executeScript` to inject a ` – jimx Jan 07 '16 at 11:12