Currently, I am in the process of developing a Chrome extension using AngularJS.
To attach a controller to the required DOM elements on a webpage, I have been utilizing the following content script code:
setController() {
if(this.setContollerCondition) {
this.controllerElement.attr('ng-controller', 'Controller as cntrl');
}
}
However, I have encountered an issue where this method is not consistently effective, as the controller constructor fails to initiate and the 'ng-scope' does not get applied to the element.
My query is regarding the appropriate approach to dynamically attach a controller. If my current method is accurate, could you help point out where I might be making mistakes?
Here is an overview of the sequence of activities occurring in the Chrome extension upon page load:
- If ng-app is not initialized, it is then initialized.
- Initialization of functions functioning as event listeners
- Checking the host URL and executing the suitable initialization function based on the URL
- If a specific DOM element is added, customised DOM elements of the extension are included, followed by utilizing the setController() function to add the Controller to the element.
Most of these functions involve asynchronous calls.
Current observed behavior includes:
- The controller is effectively implemented and operates seamlessly with a particular host like web.whatsapp.com
- All extension buttons are correctly positioned and perform exceptionally well within this host environment.
- In another scenario with a different host, such as www.linkedin.com, the controller is sporadically set and at times not set.
- Occasionally, the button is placed but when it is not, the ng-scope attribute is not applied to the DOM element due to the failure of initializing the controller constructor.
- For a third host, in this case mail.google.com, the controller is never set.
- While the button is always included, the scope is not applied to the necessary DOM element and the Controller constructor remains uninvoked.
The project incorporates Webpack and ES6 for its development requirements.
Provided below are some files resembling the actual code structure to facilitate a better understanding of the problem:
manifest.json
{
"manifest_version": 2,
"name": "MyExtension",
"short_name": "MyExtension",
"omnibox": {
"keyword": "MyExtension"
},
"description": "Description",
"version": "2.0.7",
"version_name": "2.0.7",
"browser_action": {
"default_icon": {
"128": "assets/images/icon-v2-128px.png",
"16": "assets/images/icon-v2-16px.png",
"48": "assets/images/icon-v2-48px.png"
},
"default_title": "MyExtension",
"default_popup": "index.html"
},
"content_scripts": [ {
"js": [ "assets/lib/angular.min.js", "assets/lib/jquery-2.2.3.min.js", "assets/lib/bootstrap.min.js", "dist/contentScript.bundle.js" ],
"css": ["assets/css/font-awesome.min.css", "assets/css/bootstrapInject.css", "assets/css/injectingStyle.css"],
"matches": ["*://*.linkedin.com/*", "*://web.whatsapp.com/*", "*://mail.google.com/*"],
"run_at": "document_end"
} ],
"background": {
"page": "background.html"
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*",
"contextMenus",
"notifications",
"unlimitedStorage",
"storage"
],
"icons": {
"128": "assets/images/icon-v2-128px.png",
"16": "assets/images/icon-v2-16px.png",
"48": "assets/images/icon-v2-48px.png",
"16": "assets/images/icon-v2-16px.png"
},
"web_accessible_resources": [
"all required files here"
],
"update_url": "https://clients2.google.com/service/update2/crx",
"content_security_policy": "script-src 'self' 'unsafe-eval' https://ssl.google-analytics.com https://connect.facebook.net https://platform.twitter.com https://staticxx.facebook.com; object-src 'self'"
}
init.js file responsible for attaching the controller:
export default class AddContactModule {
constructor() {
// Code logic goes here...
}
// More functions and operations are defined within this class for handling events and adding contact models.
A snippet from the controller.js file:
"use strict";
import AddContactModule from './init'
export default class ContactModalController {
constructor($scope, $compile) {
// Initialization and declaration of essential objects required for smooth operation.
}
// Additional methods and functionalities like fetching details from LinkedIn are showcased here.