BEX的类型

如前所述,Quasar可以处理浏览器扩展所在的各种位置,即“新建的选项卡”、“网页”、“开发工具选项”或“弹出窗口”。 您不需要每个位置的单独的Quasar应用程序。 您可以使用router进行一些便捷的工作。

新建的选项卡

这是BEX运行的默认方式。 通过单击浏览器中的BEX图标可以访问它。 Quasar应用程序将在新的(空白)选项卡中运行。

开发工具、选项和弹出窗口

这些都遵循相同的模式,设置路由并配置manifest.json文件以在尝试显示其中一种类型时查看该路由。 例如:

// routes.js:

const routes = [
  { path: '/options', component: () => import('pages/OptionsPage.vue') },
  { path: '/popup', component: () => import('pages/PopupPage.vue') },
  { path: '/devtools', component: () => import('pages/DevToolsPage.vue') }
]

您可以使用以下命令配置manifest.json文件,以便从该路由加载选项页面:

{
  "name": "My extension",
  ...
  "options_page": "www/index.html#/options", // Options Page
  ...
  "browser_action": {
    "default_popup": "www/index.html#/popup" // Popup Page
  },
  ...
  "devtools_page": "www/index.html#/devtools", // Dev Tools
}

网页

这才是真正的力量所在。通过一点点独创性,我们可以将Quasar应用程序注入到网页中并将其用作覆盖,从而使我们的Quasar应用程序看起来像是页面体验的一部分。

以下是如何实现此目标的简要概述:

  • src-bex/js/content-hooks.js

这里的想法是创建一个IFrame并将我们的Quasar应用添加到其中,然后将其注入到页面中。

鉴于我们的Quasar应用程序可能需要占用窗口的整个高度(从而停止与基础页面的任何交互),因此我们有一个事件来处理设置IFrame的高度。 默认情况下,IFrame的高度刚好足以允许Quasar工具栏显示(进而允许与页面的其余部分进行交互)。

每当我们知道要打开drawer并因此更改IFrame的高度以使整个绘图可见时,就可以从Quasar应用程序中调用此事件。

const
  iFrame = document.createElement('iframe'),
  defaultFrameHeight = '62px'

/**
 * Set the height of our iFrame housing our BEX
 * @param height
 */
const setIFrameHeight = height => {
  iFrame.height = height
}

/**
 * Reset the iFrame to its default height e.g The height of the top bar.
 */
const resetIFrameHeight = () => {
  setIFrameHeight(defaultFrameHeight)
}

/**
 * Content hooks which listen for messages from the BEX in the iFrame
 * @param bridge
 */
export default function attachContentHooks (bridge) {
  /**
   * When the drawer is toggled set the iFrame height to take the whole page.
   * Reset when the drawer is closed.
   */
  bridge.on('wb.drawer.toggle', event => {
    const payload = event.data
    if (payload.open) {
      setIFrameHeight('100%')
    } else {
      resetIFrameHeight()
    }
    bridge.send(event.eventResponseKey)
  })
}

/**
 * The code below will get everything going. Initialize the iFrame with defaults and add it to the page.
 * @type {string}
 */
iFrame.id = 'bex-app-iframe'
iFrame.width = '100%'
resetIFrameHeight()

// Assign some styling so it looks seamless
Object.assign(iFrame.style, {
  position: 'fixed',
  top: '0',
  right: '0',
  bottom: '0',
  left: '0',
  border: '0',
  zIndex: '9999999', // Make sure it's on top
  overflow: 'visible'
})

;(function () {
  // When the page loads, insert our browser extension app.
  iFrame.src = chrome.runtime.getURL(`www/index.html`)
  document.body.prepend(iFrame)
})()
  • src-bex/css/content-css.css

在文档顶部添加页边距,以使Quasar工具栏不会与实际页面内容重叠。

.target-some-header-class {
  margin-top: 62px;
}
  • Quasar App

然后在Quasar应用程序(/src)中,我们有一个函数可以切换drawer并将事件发送到内容脚本,告诉它调整IFrame的大小,从而使我们的整个应用程序可见:

<q-drawer :value="drawerIsOpen" @input="drawerToggled">
  Some Content
</q-drawer>
methods: {
  drawerToggled () {
    this.$q.bex
      .send('wb.drawer.toggle', {
        open: this.drawerIsOpen // So it knows to make it bigger / smaller
      })
      .then(r => {
        // Only set this once the promise has resolved so we can see the entire slide animation.
        this.drawerIsOpen = !this.drawerIsOpen
      })
  }
}

现在,您已经在网页中运行了Quasar应用程序。 您现在可以通过Quasar应用触发其他事件,其中内容脚本可以侦听基础页面并与之交互。