diff --git a/filenames.gypi b/filenames.gypi index 2b87e36fa4d2..87ff5dc9813e 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -63,8 +63,10 @@ 'lib/renderer/api/remote.js', 'lib/renderer/api/screen.js', 'lib/renderer/api/web-frame.js', + 'lib/renderer/extensions/event.js', 'lib/renderer/extensions/i18n.js', 'lib/renderer/extensions/storage.js', + 'lib/renderer/extensions/web-navigation.js', ], 'js2c_sources': [ 'lib/common/asar.js', diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index 098f3aa7c8af..bd71feb8844a 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -97,17 +97,42 @@ const removeBackgroundPages = function (manifest) { delete backgroundPages[manifest.extensionId] } -// Dispatch tabs events. -const hookWebContentsForTabEvents = function (webContents) { - const tabId = webContents.id +const sendToBackgroundPages = function (...args) { for (const page of objectValues(backgroundPages)) { - page.webContents.sendToAll('CHROME_TABS_ONCREATED', tabId) + page.webContents.sendToAll(...args) } +} + +// Dispatch web contents events to Chrome APIs +const hookWebContentsEvents = function (webContents) { + const tabId = webContents.id + + sendToBackgroundPages('CHROME_TABS_ONCREATED') + + webContents.on('will-navigate', (event, url) => { + sendToBackgroundPages('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', { + frameId: 0, + parentFrameId: -1, + processId: webContents.getId(), + tabId: tabId, + timeStamp: Date.now(), + url: url + }) + }) + + webContents.on('did-navigate', (event, url) => { + sendToBackgroundPages('CHROME_WEBNAVIGATION_ONCOMPLETED', { + frameId: 0, + parentFrameId: -1, + processId: webContents.getId(), + tabId: tabId, + timeStamp: Date.now(), + url: url + }) + }) webContents.once('destroyed', () => { - for (const page of objectValues(backgroundPages)) { - page.webContents.sendToAll('CHROME_TABS_ONREMOVED', tabId) - } + sendToBackgroundPages('CHROME_TABS_ONREMOVED', tabId) }) } @@ -245,7 +270,7 @@ const loadDevToolsExtensions = function (win, manifests) { app.on('web-contents-created', function (event, webContents) { if (!isWindowOrWebView(webContents)) return - hookWebContentsForTabEvents(webContents) + hookWebContentsEvents(webContents) webContents.on('devtools-opened', function () { loadDevToolsExtensions(webContents, objectValues(manifestMap)) }) diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index fdc16f7375d2..6c28c98edf44 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -1,31 +1,9 @@ const {ipcRenderer} = require('electron') +const Event = require('./extensions/event') const url = require('url') let nextId = 0 -class Event { - constructor () { - this.listeners = [] - } - - addListener (callback) { - this.listeners.push(callback) - } - - removeListener (callback) { - const index = this.listeners.indexOf(callback) - if (index !== -1) { - this.listeners.splice(index, 1) - } - } - - emit (...args) { - for (const listener of this.listeners) { - listener(...args) - } - } -} - class Tab { constructor (tabId) { this.id = tabId @@ -183,7 +161,7 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { onMessage: chrome.runtime.onMessage } - chrome.storage = require('./extensions/storage.js') + chrome.storage = require('./extensions/storage') chrome.pageAction = { show () {}, @@ -195,5 +173,6 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) { getPopup () {} } - chrome.i18n = require('./extensions/i18n.js').setup(extensionId) + chrome.i18n = require('./extensions/i18n').setup(extensionId) + chrome.webNavigation = require('./extensions/web-navigation').setup() } diff --git a/lib/renderer/extensions/event.js b/lib/renderer/extensions/event.js new file mode 100644 index 000000000000..4a951407f594 --- /dev/null +++ b/lib/renderer/extensions/event.js @@ -0,0 +1,24 @@ +class Event { + constructor () { + this.listeners = [] + } + + addListener (callback) { + this.listeners.push(callback) + } + + removeListener (callback) { + const index = this.listeners.indexOf(callback) + if (index !== -1) { + this.listeners.splice(index, 1) + } + } + + emit (...args) { + for (const listener of this.listeners) { + listener(...args) + } + } +} + +module.exports = Event diff --git a/lib/renderer/extensions/web-navigation.js b/lib/renderer/extensions/web-navigation.js new file mode 100644 index 000000000000..19faa8001911 --- /dev/null +++ b/lib/renderer/extensions/web-navigation.js @@ -0,0 +1,21 @@ +const Event = require('./event') +const {ipcRenderer} = require('electron') + +class WebNavigation { + constructor () { + this.onBeforeNavigate = new Event() + this.onCompleted = new Event() + + ipcRenderer.on('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event, details) => { + this.onBeforeNavigate.emit(details) + }) + + ipcRenderer.on('CHROME_WEBNAVIGATION_ONCOMPLETED', (event, details) => { + this.onCompleted.emit(details) + }) + } +} + +exports.setup = () => { + return new WebNavigation() +}