Search code examples
angularjsgoogle-chrome-extensionangularjs-components

AngularJS components to build Chrome Extension


I'm building a Chrome extension and surprisingly, I could create one AngularJS app for the extension side and another for the content script side. The latter is useful to work with a modal-like element injected in the page. I injected this app with this content script:

var myApp = angular.module('ContentApp', []);
/**
 * Append the app to the page.
 */
$.get(chrome.runtime.getURL('templates/modal.html'), function(data) {
  $($.parseHTML(data)).appendTo('body');

  // Manually bootstrapping AngularJS app because template was also manually imported.
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['ContentApp']);
  });
});

The problem comes now that modal.html is getting big and I still have to add more elements. I thought that I could start creating components in Angular and did it like this:

angular.module('ContentApp').
  component('greetUser', {
    template: 'Hello, {{$ctrl.user}}!',
    controller: function GreetUserController() {
      this.user = 'world';
    }
  });

This actually works. I can see the Hello, world message in the rendered page. But when I changed template for templateUrl, it failed:

// This doesn't work
templateUrl: 'templates/component.html',

// Neither does this
templateUrl: 'templates/component.html',

// Although this is similar to the way I got the main template, it didn't worked either
templateUrl: chrome.runtime.getURL('templates/component.html'),

Worth to mention that I added the permission to manifest.json:

  "web_accessible_resources": [
    "templates/*"
  ],

The error that I got in the console is this:

Error: [$sce:insecurl] http://errors.angularjs.org/1.5.11/$sce/insecurl?p0=chrome-extension%3A%2F%2Fext_id%2Ftemplates%2Fmodal.html
    at chrome-extension://ext_id/scripts/lib/angular.min.js:6:426
    at getTrusted (chrome-extension://ext_id/scripts/lib/angular.min.js:154:156)

Does anyone know how to make it work? Or am I asking too much for a Chrome extension?


Solution

  • I found the answer in this link. Thanks to faboolous who pointed me in the right direction ;)

    Since templateURL is processed before $scope execution, the proper way to secure a template path in a Chrome extension is this:

    // This works. Yay!
        angular.module('ContentApp').
          component('greetUser', {
            templateUrl: ['$sce', function ($sce) {
              return $sce.trustAsResourceUrl(chrome.runtime.getURL('templates/component.html'));
            }],
            controller: function ($scope) {
        ...