GithubHelp home page GithubHelp logo

isabella232 / framebus Goto Github PK

View Code? Open in Web Editor NEW

This project forked from braintree/framebus

0.0 0.0 0.0 1.12 MB

A message bus that operates across iframes

License: MIT License

JavaScript 26.88% HTML 6.31% TypeScript 66.81%

framebus's Introduction

Framebus Build Status npm version

Framebus allows you to easily send messages across frames (and iframes) with a simple bus.

In one frame:

var Framebus = require("framebus");
var bus = new Framebus();

bus.emit("message", {
  from: "Ron",
  contents: "they named it...San Diago",
});

In another frame:

var Framebus = require("framebus");
var bus = new Framebus();

bus.on("message", function (data) {
  console.log(data.from + " said: " + data.contents);
});

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

type FramebusOptions = {
  origin?: string, // default: "*"
  channel?: string, // no default
  verifyDomain?: (url: string) => boolean, // no default
};

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 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.

var bus = new Framebus({
  verifyDomain: function (url) {
    // only return true if the domain of the url matches exactly
    url.indexOf("https://my-domain") === 0;
  },
});

API

target(options: FramebusOptions): framebus

returns: a chainable instance of framebus that operates on the chosen origin.

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.

framebus
  .target({
    origin: "https://example.com",
  })
  .on("my cool event", function () {});
// will ignore all incoming 'my cool event' NOT from 'https://example.com'
Argument Type Description
options FramebusOptions See above section for more details

emit('event', data? , callback?): boolean

returns: true if the event was successfully published, false otherwise

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

on('event', fn): boolean

returns: true if the subscriber was successfully added, 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
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

off('event', fn): boolean

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

var popup = window.open("https://example.com");

framebus.include(popup);
framebus.emit("hello popup and friends!");
Argument Type Description
popup Window The popup refrence returned by window.open

teardown(): void

Calls off on all listeners used for this bus instance and makes subsequent calls to all methods noop.

bus.on("event-name", handler);

// event-name listener is torn down
bus.teardown();

// these now do nothing
bus.on("event-name", handler);
bus.emit("event-name", data);
bus.off("event-name", handler);

Pitfalls

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 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.

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).

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 as the event name. The events occur as follows:

  1. http://emitter.example.com publishes an event with a function as the event data

    var callback = function (data) {
      console.log("Got back %s as a reply!", data);
    };
    
    framebus.emit("Marco!", callback, "http://listener.example.com");
  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.

  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.

  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

    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

framebus's People

Contributors

crookedneighbor avatar braintreeps avatar mrak avatar jeffcarp avatar evanhahn avatar lilaconlee avatar quinnjn avatar dependabot[bot] avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.