Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run chrome extension that is made by Angular, inside iframe

I am trying to implement a simple Chrome extension that renders its content not on a default popup , but on a sidebar. I've realized that to do that I must use an iframe due to its default behavior of chrome extension popup style.(which it has limitation of maximum width size of 800px and height 600px. And also unable to style its position).

Angular Chrome Extension Scaffold Project

Above the link is a github repository of a Angular Chrome extension scaffold project and I'm trying to build a chrome extension with Angular.

{
  "manifest_version": 2,
  "name": "extension test",
  "short_name": "extension test",
  "version": "1.0.0",
  "description": "extension test",
  "permissions": [
    "tabs",
    "downloads",
    "storage",
    "activeTab",
    "declarativeContent"
  ],
  "browser_action": {
    "default_popup": "index.html",
    "default_title": "extension test",
    "default_icon": {
      "16": "assets/images/favicon-16.png",
      "32": "assets/images/favicon-32.png",
      "48": "assets/images/favicon-48.png",
      "128": "assets/images/favicon-128.png"
    }
  },
  "options_ui": {
    "page": "index.html#/option",
    "open_in_tab": false
  },
  "content_scripts": [
    {
      "js": ["contentPage.js"],
      "matches": ["<all_urls>"]
    }
  ],
  "background": {
    "scripts": ["backgroundPage.js"],
    "persistent": false
  },
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "default_icon": {
    "16": "assets/images/favicon-16.png",
    "32": "assets/images/favicon-32.png",
    "48": "assets/images/favicon-48.png",
    "128": "assets/images/favicon-128.png"
  }
}

Above is my manifest.json file.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Falcon Image Crawler</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

And here's what index.html looks like.

and last here is how my App.component.ts looks like

export class PopupComponent implements OnInit {
  constructor() {
  }

  public ngOnInit(): void {
    chrome.tabs.executeScript({
      code: `
      (function(){
      const iframe = document.createElement('iframe');
      iframe.src = chrome.runtime.getURL('index.html');
      iframe.style.cssText = 'position:fixed;top:0;left:0;display:block;' +
        'width:300px;height:100%;z-index:1000;';
      document.body.appendChild(iframe);
    })(); `
    });
  }
}

When I click an icon of my chrome extension an Iframe element shows up left side of the browser but cannot load index.html with "Unchecked runtime.lastError: Cannot access a chrome:// URL" error and also popup shows up.

image to describe its behavior (image to describe its behavior)

Is there a right way to run chrome extension not on its default popup but on a iframe that i can style it without any limitation?

like image 534
Chanwoo Park Avatar asked May 03 '19 08:05

Chanwoo Park


1 Answers

You need to add your index.html to the array of Web accessible resources, like so:

{
  "manifest_version": 2,
  "name": "extension test",
  "short_name": "extension test",
  "version": "1.0.0",
  "description": "extension test",
  "web_accessible_resources": [
    "index.html"
  ],
  "permissions": [
    "tabs",
    "downloads",
    "storage",
    "activeTab",
    "declarativeContent"
  ],
  "browser_action": {
    "default_popup": "index.html",
    "default_title": "extension test",
    "default_icon": {
      "16": "assets/images/favicon-16.png",
      "32": "assets/images/favicon-32.png",
      "48": "assets/images/favicon-48.png",
      "128": "assets/images/favicon-128.png"
    }
  },
  "options_ui": {
    "page": "index.html#/option",
    "open_in_tab": false
  },
  "content_scripts": [
    {
      "js": ["contentPage.js"],
      "matches": ["<all_urls>"]
    }
  ],
  "background": {
    "scripts": ["backgroundPage.js"],
    "persistent": false
  },
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "default_icon": {
    "16": "assets/images/favicon-16.png",
    "32": "assets/images/favicon-32.png",
    "48": "assets/images/favicon-48.png",
    "128": "assets/images/favicon-128.png"
  }
}

Also, you should not need to use chrome.tabs.executeScript if you want to include your script in any page, but use the manifest syntax.

like image 127
Antoine Bolvy Avatar answered Nov 01 '22 23:11

Antoine Bolvy