}).join('')
const html = new Buffer(`<html><body>${scripts}</body></html>`)
- const contents = webContents.create({})
+ const contents = webContents.create({
+ commandLineSwitches: ['--background-page']
+ })
backgroundPages[manifest.extensionId] = { html: html, webContents: contents }
contents.loadURL(url.format({
protocol: 'chrome-extension',
}
const portId = ++nextId
- event.returnValue = {webContentsId: page.webContents.id, portId: portId}
+ event.returnValue = {tabId: page.webContents.id, portId: portId}
event.sender.once('render-view-deleted', () => {
if (page.webContents.isDestroyed()) return
page.webContents.sendToAll(`CHROME_RUNTIME_ONMESSAGE_${extensionId}`, event.sender.id, message)
})
-ipcMain.on('CHROME_TABS_EXECUTESCRIPT', function (event, requestId, webContentsId, extensionId, details) {
- const contents = webContents.fromId(webContentsId)
+ipcMain.on('CHROME_TABS_SEND_MESSAGE', function (event, tabId, extensionId, isBackgroundPage, message) {
+ const contents = webContents.fromId(tabId)
+ if (!contents) {
+ console.error(`Sending message to unkown tab ${tabId}`)
+ return
+ }
+
+ const senderTabId = isBackgroundPage ? null : event.sender.id
+
+ contents.sendToAll(`CHROME_RUNTIME_ONMESSAGE_${extensionId}`, senderTabId, message)
+})
+
+ipcMain.on('CHROME_TABS_EXECUTESCRIPT', function (event, requestId, tabId, extensionId, details) {
+ const contents = webContents.fromId(tabId)
if (!contents) {
- console.error(`Sending message to unkown webContentsId ${webContentsId}`)
+ console.error(`Sending message to unkown tab ${tabId}`)
return
}
}
class Tab {
- constructor (webContentsId) {
- this.id = webContentsId
+ constructor (tabId) {
+ this.id = tabId
}
}
class MessageSender {
- constructor (webContentsId, extensionId) {
- this.tab = new Tab(webContentsId)
+ constructor (tabId, extensionId) {
+ this.tab = tabId ? new Tab(tabId) : null
this.id = extensionId
this.url = `chrome-extension://${extensionId}`
}
}
class Port {
- constructor (webContentsId, portId, extensionId, name) {
- this.webContentsId = webContentsId
+ constructor (tabId, portId, extensionId, name) {
+ this.tabId = tabId
this.portId = portId
this.disconnected = false
this.name = name
this.onDisconnect = new Event()
this.onMessage = new Event()
- this.sender = new MessageSender(webContentsId, extensionId)
+ this.sender = new MessageSender(tabId, extensionId)
ipcRenderer.once(`CHROME_PORT_DISCONNECT_${portId}`, () => {
this._onDisconnect()
disconnect () {
if (this.disconnected) return
- ipcRenderer.sendToAll(this.webContentsId, `CHROME_PORT_DISCONNECT_${this.portId}`)
+ ipcRenderer.sendToAll(this.tabId, `CHROME_PORT_DISCONNECT_${this.portId}`)
this._onDisconnect()
}
postMessage (message) {
- ipcRenderer.sendToAll(this.webContentsId, `CHROME_PORT_POSTMESSAGE_${this.portId}`, message)
+ ipcRenderer.sendToAll(this.tabId, `CHROME_PORT_POSTMESSAGE_${this.portId}`, message)
}
_onDisconnect () {
}
// Inject chrome API to the |context|
-exports.injectTo = function (extensionId, context) {
+exports.injectTo = function (extensionId, isBackgroundPage, context) {
const chrome = context.chrome = context.chrome || {}
- ipcRenderer.on(`CHROME_RUNTIME_ONCONNECT_${extensionId}`, (event, webContentsId, portId, connectInfo) => {
- chrome.runtime.onConnect.emit(new Port(webContentsId, portId, extensionId, connectInfo.name))
+ ipcRenderer.on(`CHROME_RUNTIME_ONCONNECT_${extensionId}`, (event, tabId, portId, connectInfo) => {
+ chrome.runtime.onConnect.emit(new Port(tabId, portId, extensionId, connectInfo.name))
})
ipcRenderer.on(`CHROME_RUNTIME_ONMESSAGE_${extensionId}`, (event, tabId, message) => {
onConnect: new Event(),
connect (...args) {
+ if (isBackgroundPage) {
+ console.error('chrome.runtime.connect is not supported in background page')
+ return
+ }
+
// Parse the optional args.
let targetExtensionId = extensionId
let connectInfo = {name: ''}
[targetExtensionId, connectInfo] = args
}
- const {webContentsId, portId} = ipcRenderer.sendSync('CHROME_RUNTIME_CONNECT', targetExtensionId, connectInfo)
- return new Port(webContentsId, portId, extensionId, connectInfo.name)
+ const {tabId, portId} = ipcRenderer.sendSync('CHROME_RUNTIME_CONNECT', targetExtensionId, connectInfo)
+ return new Port(tabId, portId, extensionId, connectInfo.name)
},
sendMessage (...args) {
+ if (isBackgroundPage) {
+ console.error('chrome.runtime.sendMessage is not supported in background page')
+ return
+ }
+
// Parse the optional args.
let targetExtensionId = extensionId
let message
if (responseCallback) {
console.error('responseCallback is not supported')
}
- ipcRenderer.send('CHROME_RUNTIME_SENDMESSAGE', extensionId, message)
+ ipcRenderer.send(`CHROME_TABS_SEND_MESSAGE`, tabId, extensionId, isBackgroundPage, message)
},
onUpdated: new Event()
})
// Process command line arguments.
-var nodeIntegration = 'false'
-var preloadScript = null
+let nodeIntegration = 'false'
+let preloadScript = null
+let isBackgroundPage = false
for (let arg of process.argv) {
if (arg.indexOf('--guest-instance-id=') === 0) {
// This is a guest web view.
nodeIntegration = arg.substr(arg.indexOf('=') + 1)
} else if (arg.indexOf('--preload=') === 0) {
preloadScript = arg.substr(arg.indexOf('=') + 1)
+ } else if (arg === '--background-page') {
+ isBackgroundPage = true
}
}
nodeIntegration = 'true'
} else if (window.location.protocol === 'chrome-extension:') {
// Add implementations of chrome API.
- require('./chrome-api').injectTo(window.location.hostname, window)
+ require('./chrome-api').injectTo(window.location.hostname, isBackgroundPage, window)
nodeIntegration = 'false'
} else {
// Override default web functions.