Using page's angular JS in chrome extension

Solution 1:

Hmm.. Actually you should be just able to change the value using vanilla Javascript or JQuery and should not need to update the scope as it is two-way binding ie. Updating the view updates the model and vice-versa.

The only reason why the model does not update is because the watchers to update the model trigger only on particular events like "click" or "input".

So the solution here would be to manually trigger these events. This can be do by:

// the selector used is based on your example.
var elementTOUpdate = $('.textbox');
input.val('new-value');
input.trigger('input');

The last statement will trigger all the handlers on the element for the "input" event ( which will fire the angular watchers ) and update the scope. More info on the trigger function: http://api.jquery.com/trigger/

Solution 2:

Although your web page and your Chrome extension's content script share the same DOM, they have separate JS execution contexts. In other words, despite grabbing the element via angular.element().scope() in your Chrome extension, you're still not accessing the correct scope object. (See the Chrome dev docs for more on this.)

In order to get the modified data from your Chrome extension on to the page, you can either manipulate the DOM via your content script, or take some extra steps to get the modified data into the web page's execution context (and subsequently, into your controller's scope).

For the latter, the solution is to use the Chrome's Message Passing API; specifically, the API designed to communicate between the web page and the Chrome extension (see here).

Here's an example from the documentation:

First, enable the API for the appropriate website(s) in your manifest.json file:

"externally_connectable": {
  "matches": ["http://*.foo.com/*"]
}

From the web page, make a request to connect to the Chrome extension. In your callback, you'd update your model:

// Chrome extension's ID
var extensionId = "abcdefghijklmnoabcdefhijklmnoabc";

chrome.runtime.sendMessage(extensionId, {foo: 'bar'},
  function(response) {
    if (response.success) {
      $scope.myData.foo = response.data;
      $scope.$apply();
    }
  });

In your Chrome extension's background.js file, add a listener for the request:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (request.foo) {
      sendResponse({ data: 'modified data goes here' });
    }
  });

This process will allow your Chrome extension to send data into the correct execution environment, allowing your AngularJS app to work with it.