Skip to content

Say hi to ceci 💅

Manuel Rueda edited this page May 13, 2017 · 2 revisions

ceci provides 4 layers to use in your Chrome Extension and allow to execute code in the page's context of different targets.

Modules

ceci is dividen in modules to allow to inject only the necessary code in each layer.

  • content-script
  • devtools
  • event-page
  • page-agent
  • page-executor
  • subscriber

Example

import ceci from 'ceci/content-script' // Best option, will only inject the necessary code
import { contentScript as ceci } from 'ceci' // Also works, but the final bundle will be bigger

Minimal setup

This is the minimal setup necessary to work with ceci.

Page Agent layer

This script is an Agent that will take care of all the heavy part of interpretare your code, run it, return values, etc. It's the heart ❤️ of ceci

This Agent will be injected in every tab that the extension has permissions (by domain) by the Content Script layer

The script will implement the ceci's page-agent module, like this:

import ceci from 'ceci/page-agent'
ceci()

Normally there is not need to have extra code in this script because ceci will take care of everything. But, this script will be executed in the context of the page, you can add helper code here and reuse it in you injected code.

Content Script layer

This Content Script will not be injected through manifest.json, this file will be injected by the Event Page layer

The Content Script's code will implement the ceci's content-script module, like this:

import ceci from 'ceci/content-script'
//URL to the script that implements the ceci's page-agent layer
const pageAgentUrl = 'page-agent.js'

ceciContentScript(pageAgentUrl)
  .then(({run, reactive}) => {
    // run and reactive are two ways to inject code into the pages (see the doc below)
    /*
      Your Event Page's code
    */
  })

Event Page layer

You need to configure a Event Page in you manifest.json, like this:

{
    "background": {
        "scripts": ["event-page.js"],
        "persistent": false
    }
}

The Event Page's code will implement the ceci's event-page module, like this:

import ceci from 'ceci/event-page'
//URL to the content-script that implements the ceci's content-script layer
const contentScriptUrl = 'content-script.js'
// run and reactive are two ways to inject code into the pages (see the doc below)
const { run, reactive } = ceci(contentScriptUrl)

/*
  Your Event Page's code
*/

Extra layers

This two types of layers are really useful but there is no need to have it to work with ceci.

devtools layer

The devtools layer allow to run code in the inspected code very easily, like this:

import ceci from 'ceci/devtools'
// run and reactive are two ways to inject code into the pages (see the doc below)
const {run, reactive} = ceci()

Page Executor module

This module can be used in any layer, contains the run and reactive to be used from anywhere. This module doesn't run all the bootstrap code that the other layers runs. So this is useful when you have multiple content scripts, event pages or even browser actions.

// run and reactive are two ways to inject code into the pages (see the doc below)
import {run, reactive} from 'ceci/page-executor'

Permissions

ceci needs tabs and activeTab extensions permissions to work, also the Page Agent must be accesible from the web using web_accessible_resources.

ceci will only work with tabs which has permission. Do not execute run or reactive if you don't have permission to the domain of the tab.

API

All the modules only expose two functions to run code.

run

This will run a sync or async function into the page.

Syntax

run(function)
run(function, parameters)
run(function, parameters, tabId)

Parameters

  • function: Function to be executed in the page context
  • parameters: Array of parameters to use to call the function (using apply)
  • tabId: Tab's id to find the tab where run the code. Only available when is called from page-executor or event-page

Return value

Promise that will resolve with the value that the function returns, will catch any error thrown by the function. If the function returns a Promise the promises are chained.

Example

import { run } from 'ceci/page-executor'
let username = 'manrueda'
let execution = run(username => {
  // The parameters will respect the array order
  return fetch(`/api/user/${id}`)
    .then(r => r.json())
}, [username])

execution.then(user => {
  console.log(user)
}).catch(error => {
  console.warn(error)
})

reactive

This allow to run code in the page and subscribe the extension to events that the function can emit. This is to avoid polling the page to detect changes.

Syntax

reactive(function)
reactive(function, parameters)
reactive(function, parameters, tabId)

Parameters

  • function: Function to be executed in the page context
  • parameters: Array of parameters to use to call the function (using apply)
  • tabId: Tab's id to find the tab where run the code. Only available when is called from page-executor or event-page

Return value

Subscriber instance (see below) that can be used to subscribe to event emitted by the code.

Example

import { reactive } from 'ceci/page-executor'
let username = 'manrueda'

let subscriber = reactive((emit, username) => {
  // The parameters will respect the array order, but always the first one will be the emit
  // Every 150ms this code will emit an event with the username using the emit function
  const interval = setInterval(function () {
    emit({username})
  }, 150)

  // The returned value must be a function that will be called when the Subscriber instance in the extension is disposed
  return () => {
    clearInterval(interval)
  }
}, [username])

// The subscribe method will register listeners for errors and events
subscriber.subscribe(event => {
  console.log(event)
}, error => {
  console.warn(error)
  subscriber.dispose()
})

Subscriber

Methods

  • subscribe([eventListener, [errorListener]]): This function attach zero, one or both type of listeners to the subscribers. Those listener will be called if an event or error is emitted in the Subscriber.
  • dispose(): Will trigger the dispose of this instance and the code in the page related with it.
  • emit([error, [event]]): This method can be called to emit events or errors in the Subscriber. Normally only used internally.
Clone this wiki locally