Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

framebus

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

framebus - npm Package Compare versions

Comparing version 6.0.0-rc.3 to 6.0.0

dist/framebus.d.ts

4

dist/index.d.ts

@@ -1,2 +0,2 @@

export * from "./methods";
export type { FramebusConfig, FramebusOptions } from "./framebus-config";
import { Framebus } from "./framebus";
export = Framebus;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./methods"), exports);
var lib_1 = require("./lib");
var framebus_1 = require("./framebus");
(0, lib_1.attach)();
module.exports = framebus_1.Framebus;

@@ -9,3 +9,3 @@ {

"homepage": "https://github.com/braintree/framebus",
"version": "6.0.0-rc.3",
"version": "6.0.0",
"main": "dist/index.js",

@@ -34,33 +34,32 @@ "files": [

"devDependencies": {
"@types/jest": "^27.4.0",
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@wdio/cli": "^7.16.15",
"@wdio/local-runner": "^7.16.15",
"@wdio/mocha-framework": "^7.16.15",
"@wdio/spec-reporter": "^7.16.14",
"@wdio/sync": "^7.16.15",
"async": "^3.2.3",
"@types/jest": "^29.4.0",
"@wdio/cli": "^7.25.2",
"@wdio/local-runner": "^7.25.2",
"@wdio/mocha-framework": "^7.25.2",
"@wdio/spec-reporter": "^7.25.1",
"@wdio/sync": "^7.25.2",
"async": "^3.2.4",
"browserify": "^17.0.0",
"chromedriver": "^98.0.1",
"chromedriver": "^118.0.1",
"del": "^6.0.0",
"ejs": "^3.1.6",
"eslint": "^8.9.0",
"ejs": "^3.1.8",
"eslint": "^8.35.0",
"eslint-config-braintree": "6.0.0-typescript-prep-rc.2",
"eslint-plugin-prettier": "^4.0.0",
"express": "^4.17.3",
"express": "^4.18.2",
"gulp": "^4.0.2",
"gulp-concat": "^2.4.2",
"gulp-remove-code": "^3.0.4",
"gulp-size": "^4.0.1",
"gulp-size": "^3.0.0",
"gulp-streamify": "^1.0.2",
"gulp-uglify": "^3.0.2",
"jest": "^27.5.1",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"morgan": "^1.10.0",
"prettier": "^2.5.1",
"ts-jest": "^27.1.3",
"prettier": "^2.8.4",
"ts-jest": "^29.0.5",
"tsify": "^5.0.4",
"typescript": "^4.5.5",
"typescript": "^5.1.6",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"wdio-chromedriver-service": "^7.2.8"
"wdio-chromedriver-service": "^8.1.1"
},

@@ -67,0 +66,0 @@ "jest": {

# Framebus [![Build Status](https://github.com/braintree/framebus/workflows/Unit%20Tests/badge.svg)](https://github.com/braintree/framebus/actions?query=workflow%3A%22Unit+Tests%22) [![Build Status](https://github.com/braintree/framebus/workflows/Functional%20Tests/badge.svg)](https://github.com/braintree/framebus/actions?query=workflow%3A%22Functional+Tests%22) [![npm version](https://badge.fury.io/js/framebus.svg)](http://badge.fury.io/js/framebus)
Framebus allows you to easily send messages across frames (and iframes).
Framebus allows you to easily send messages across frames (and iframes)
with a simple bus.

@@ -8,7 +9,6 @@ In one frame:

```js
import { initialize as initializeFramebus, emit } from "framebus";
var Framebus = require("framebus");
var bus = new Framebus();
const bus = initializeFramebus();
emit(bus, "message", {
bus.emit("message", {
from: "Ron",

@@ -22,7 +22,6 @@ contents: "they named it...San Diago",

```js
import { initialize as initializeFramebus, on } from "framebus";
var Framebus = require("framebus");
var bus = new Framebus();
const bus = initializeFramebus();
on(bus, "message", (data) => {
bus.on("message", function (data) {
console.log(data.from + " said: " + data.contents);

@@ -32,3 +31,4 @@ });

The Framebus class takes a configuration object, where all the params are optional.
The Framebus class takes a configuration object, where all the params
are optional.

@@ -40,16 +40,23 @@ ```js

verifyDomain?: (url: string) => boolean, // no default
targetFrames?: <HTMLFrameElement | Window>[], // by default, all frames available to broadcast to
};
```
The `origin` sets the framebus configuration to only operate on the chosen origin.
The `origin` sets the framebus instance to only operate on the chosen
origin.
The `channel` namespaces the events called with `on` and `emit` so you can have multiple buses on the page and have them only communicate with buses with the same channel value.
The `channel` namespaces the events called with `on` and `emit` so you
can have multiple bus instances on the page and have them only
communicate with busses with the same channel value.
If a `verifyDomain` is passed, then the `on` listener will only fire if the domain of the origin of the post message matches the `location.href` value of page or the function passed for `verifyDomain` returns `true`.
If a `verifyDomain` function is passed, then the `on` listener will only
fire if the domain of the origin of the post message matches the
`location.href` value of page or the function passed for `verifyDomain`
returns `true`.
```js
const bus = initializeFramebus({
verifyDomain(url) {
var bus = new Framebus({
verifyDomain: function (url) {
// only return true if the domain of the url matches exactly
return url.startsWith("https://my-domain/");
url.indexOf("https://my-domain") === 0;
},

@@ -59,94 +66,159 @@ });

If a `targetFrames` array is passed, then framebus will only send
messages to those frames and listen for messages from those frames. You
can pass a reference to a `Window` (the return value of `window.open`)
or an `HTMLFrameElement` (a DOM node representing an iframe).
```js
var myIframe = document.getElementById("my-iframe");
var bus = new Framebus({
targetFrames: [myIframe],
});
```
To add additional frames to the `targetFrames` array in the future, use
the `addTargetFrame` method. `targetFrames` must be set, even if it's an
empty array, for this method to work.
```js
var myIframe = document.getElementById("my-iframe");
var bus = new Framebus({
targetFrames: [],
});
bus.addTargetFrame(myIframe);
```
## API
#### `emit<T = unknown>(config, 'event', data?, callback?): boolean`
#### `target(options: FramebusOptions): framebus`
**returns**: `true` if the event was successfully published, `false` otherwise
**returns**: a chainable instance of framebus that operates on the
chosen origin.
| Argument | Type | Description |
| ---------------- | -------------- | ---------------------------------------------------- |
| `config` | FramebusConfig | The Framebus configuration to use |
| `event` | String | The name of the event |
| `data` | Object | The data to give to subscribers |
| `callback(data)` | Function | Give subscribers a function for easy, direct replies |
This method is used in conjuction with `emit`, `on`, and `off` to
restrict their results to the given origin. By default, an origin of
`'*'` is used.
#### `emitAsPromise<T = unknown>('event', data?): Promise<T>`
```javascript
framebus
.target({
origin: "https://example.com",
})
.on("my cool event", function () {});
// will ignore all incoming 'my cool event' NOT from 'https://example.com'
```
**returns**: A promise that resolves when the emitted event is responded to the first time. It will reject if the event could not be succesfully published.
| Argument | Type | Description |
| --------- | --------------- | ---------------------------------- |
| `options` | FramebusOptions | See above section for more details |
| Argument | Type | Description |
| -------- | -------------- | --------------------------------- |
| `config` | FramebusConfig | The Framebus configuration to use |
| `event` | String | The name of the event |
| `data` | Object | The data to give to subscribers |
#### `emit('event', data?, callback?): boolean`
**Note:**: If the `replyCallback` is used with `on` (see below), `emitAsPromise` will only resolve for the first `replyCallback`. Any subsequent calls to `replyCallback` will be ignored.
**returns**: `true` if the event was successfully published, `false`
otherwise
#### `on(config, 'event', fn): boolean`
| Argument | Type | Description |
| ---------------- | -------- | ---------------------------------------------------- |
| `event` | String | The name of the event |
| `data` | Object | The data to give to subscribers |
| `callback(data)` | Function | Give subscribers a function for easy, direct replies |
**returns**: `true` if the subscriber was successfully added, `false` otherwise
#### `emitAsPromise('event', data?): Promise`
Unless already bound to a scope, the listener will be executed with `this` set
to the `MessageEvent` received over postMessage.
**returns**: A promise that resolves when the emitted event is responded
to the first time. It will reject if the event could not be succesfully
published.
| Argument | Type | Description |
| ---------------------- | -------------- | ----------------------------------------------------------- |
| `config` | FramebusConfig | The Framebus configuration to use |
| `event` | String | The name of the event |
| `fn(data?, callback?)` | Function | Event handler. Arguments are from the `emit` invocation |
| ↳ `this` | scope | The `MessageEvent` object from the underlying `postMessage` |
| Argument | Type | Description |
| -------- | ------ | ------------------------------- |
| `event` | String | The name of the event |
| `data` | Object | The data to give to subscribers |
#### `once(config, 'event', fn): boolean`
Using this method assumes the browser context you are using supports
Promises. If it does not, set a polyfill for the Framebus class with
`setPromise`
**returns**: `true` if the subscriber was successfully added, `false` otherwise
```js
// or however you want to polyfill the promise
const PolyfilledPromise = require("promise-polyfill");
This is essentially the same as `on`, except it will only ever trigger once. It's equivalent to using `on` and then calling `off` as soon as the callback is called.
Framebus.setPromise(PolyfilledPromise);
```
| Argument | Type | Description |
| ---------------------- | -------------- | ----------------------------------------------------------- |
| `config` | FramebusConfig | The Framebus configuration to use |
| `event` | String | The name of the event |
| `fn(data?, callback?)` | Function | Event handler. Arguments are from the `emit` invocation |
| ↳ `this` | scope | The `MessageEvent` object from the underlying `postMessage` |
#### `on('event', fn): boolean`
#### `off(config, 'event', fn): boolean`
**returns**: `true` if the subscriber was successfully added, `false`
otherwise
**returns**: `true` if the subscriber was successfully removed, `false` otherwise
Unless already bound to a scope, the listener will be executed with
`this` set to the `MessageEvent` received over
postMessage.
| Argument | Type | Description |
| -------- | -------------- | --------------------------------- |
| `config` | FramebusConfig | The Framebus configuration to use |
| `event` | String | The name of the event |
| `fn` | Function | The function that was subscribed |
| Argument | Type | Description |
| ---------------------- | -------- | ----------------------------------------------------------- |
| `event` | String | The name of the event |
| `fn(data?, callback?)` | Function | Event handler. Arguments are from the `emit` invocation |
| ↳ `this` | scope | The `MessageEvent` object from the underlying `postMessage` |
#### `include(config, popup): boolean`
#### `off('event', fn): boolean`
**returns**: `true` if the popup was successfully included, `false` otherwise
**returns**: `true` if the subscriber was successfully removed, `false`
otherwise
| Argument | Type | Description |
| -------- | -------- | -------------------------------- |
| `event` | String | The name of the event |
| `fn` | Function | The function that was subscribed |
#### `include(popup): boolean`
**returns**: `true` if the popup was successfully included, `false`
otherwise
```javascript
const popup = window.open("https://example.com");
var popup = window.open("https://example.com");
include(bus, popup);
emit(bus, "hello popup and friends!");
framebus.include(popup);
framebus.emit("hello popup and friends!");
```
| Argument | Type | Description |
| -------- | -------------- | -------------------------------------------- |
| `config` | FramebusConfig | The Framebus configuration to use |
| `popup` | Window | The popup refrence returned by `window.open` |
| Argument | Type | Description |
| -------- | ------ | -------------------------------------------- |
| `popup` | Window | The popup refrence returned by `window.open` |
#### `addTargetFrame(frame): boolean`
Used in conjunction with `targetFrames` configuration. If a
`targetFrames` array is not passed on instantiation, this method will
noop.
```javascript
var frame = document.getElementById("my-iframe");
framebus.addTargetFrame(frame);
framebus.emit("hello targetted iframe!");
```
| Argument | Type | Description |
| -------- | --------------------------- | -------------------------------------------- |
| `frame` | Window or HTMLIFrameElement | The iframe or popup to add to `targetFrames` |
#### `teardown(): void`
Calls `off` on all listeners used for this bus instance and makes subsequent calls to all methods `noop`.
Calls `off` on all listeners used for this bus instance and makes
subsequent calls to all methods `noop`.
```javascript
on(bus, "event-name", handler);
bus.on("event-name", handler);
// the listener for the "event-name" event is removed
teardown(bus);
// event-name listener is torn down
bus.teardown();
// these now do nothing
on(bus, "event-name", handler);
emit(bus, "event-name", data);
off(bus, "event-name", handler);
bus.on("event-name", handler);
bus.emit("event-name", data);
bus.off("event-name", handler);
```

@@ -156,71 +228,78 @@

These are some things to keep in mind while using **framebus** to handle your
event delegation
These are some things to keep in mind while using **framebus** to handle
your event delegation
### Cross-site scripting (XSS)
**framebus** allows convenient event delegation across iframe borders. By
default it will broadcast events to all iframes on the page, regardless of
origin. Use the optional `origin` parameter when you know the exact domain of
the iframes you are communicating with. This will protect your event data from
malicious domains.
**framebus** allows convenient event delegation across iframe borders.
By default it will broadcast events to all iframes on the page,
regardless of origin. Use the optional `target()` method when you know
the exact domain of the iframes you are communicating with. This will
protect your event data from malicious domains.
### Data is serialized as JSON
**framebus** operates over `postMessage` using `JSON.parse` and `JSON.stringify`
to facilitate message data passing. Keep in mind that not all JavaScript objects
serialize cleanly into and out of JSON, such as `undefined`.
**framebus** operates over `postMessage` using `JSON.parse` and
`JSON.stringify` to facilitate message data passing. Keep in mind that
not all JavaScript objects serialize cleanly into and out of JSON, such
as `undefined`.
### Asynchronicity
Even when the subscriber and publisher are within the same frame, events go
through `postMessage`. Keep in mind that `postMessage` is an asynchronous
protocol and that publication and subscription handling occur on separate
iterations of the [event
loop (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop#Event_loop).
Even when the subscriber and publisher are within the same frame, events
go through `postMessage`. Keep in mind that `postMessage` is an
asynchronous protocol and that publication and subscription handling
occur on separate iterations of the [event loop
(MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop#Event_loop).
### Published callback functions are an abstraction
When you specify a `callback` while using `emit`, the function is not actually
given to the subscriber. The subscriber receives a one-time-use function that is
generated locally by the subscriber's **framebus**. This one-time-use callback function
is pre-configured to publish an event back to the event origin's domain using a
[UUID](http://tools.ietf.org/html/rfc4122) as the event name. The events occur
as follows:
When you specify a `callback` while using `emit`, the function is not
actually given to the subscriber. The subscriber receives a one-time-use
function that is generated locally by the subscriber's **framebus**.
This one-time-use callback function is pre-configured to publish an
event back to the event origin's domain using a
[UUID](http://tools.ietf.org/html/rfc4122) as the event name. The events
occur as follows:
1. `http://emitter.example.com` publishes an event with a function as the event data
1. `http://emitter.example.com` publishes an event with a function as
the event data
```javascript
const callback = function (data) {
console.log("Got back %s as a reply!", data);
};
```javascript
var callback = function (data) {
console.log("Got back %s as a reply!", data);
};
emit(bus, "Marco!", callback);
```
framebus.emit("Marco!", callback, "http://listener.example.com");
```
1. The **framebus** on `http://emitter.example.com` generates a UUID as an event name
and adds the `callback` as a subscriber to this event.
1. The **framebus** on `http://listener.example.com` sees that a special callback
event is in the event payload. A one-time-use function is created locally and
given to subscribers of `'Marco!'` as the event data.
1. The subscriber on `http://listener.example.com` uses the local one-time-use
callback function to send data back to the emitter's origin
2. The **framebus** on `http://emitter.example.com` generates a UUID as
an event name and adds the `callback` as a subscriber to this event.
```javascript
const bus = initializeFramebus({
origin: "http://emitter.example.com")
});
3. The **framebus** on `http://listener.example.com` sees that a
special callback event is in the event payload. A one-time-use
function is created locally and given to subscribers of `'Marco!'`
as the event data.
on(bus, "Marco!", function (callback) {
callback("Polo!");
});
```
4. The subscriber on `http://listener.example.com` uses the local
one-time-use callback function to send data back to the emitter's
origin
1. The one-time-use function on `http://listener.example.com` publishes an event
as the UUID generated in **step 2** to the origin that emitted the event.
1. Back on `http://emitter.example.com`, the `callback` is called and
unsubscribed from the special UUID event afterward.
```javascript
framebus
.target("http://emitter.example.com")
.on("Marco!", function (callback) {
callback("Polo!");
});
```
5. The one-time-use function on `http://listener.example.com` publishes
an event as the UUID generated in **step 2** to the origin that
emitted the event.
6. Back on `http://emitter.example.com`, the `callback` is called and
unsubscribed from the special UUID event afterward.
## Development and contributing
See [**CONTRIBUTING.md**](CONTRIBUTING.md)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc