Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADT-1567] Update documentation #2

Merged
merged 5 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
coverage
*.vscode
build
build
.DS_Store
19 changes: 19 additions & 0 deletions Contributors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Contributors

## Special thanks to:

The original author of Frame Events:
* [Ulises Soriano Palao](https://github.com/ulisessp)

Other engineers involved:
* [Oluwafemi Akinde](https://github.com/SirPhemmiey)
* [Vu Nam Nguyen](https://github.com/vunam)

## I would like to join this list. How can I help the project?

This is a project that is actively used, feel free to contribute, if you think you can help out with the following:

- [ ] Bug fixes
- [ ] Make more generic
- [ ] Enhance the package
- [ ] More documentation & examples
211 changes: 211 additions & 0 deletions LICENSE.md

Large diffs are not rendered by default.

110 changes: 34 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,62 @@
# 🔗 Frame Events ![Coverage](https://github.com/WeTransfer/frame-events/wiki/coverage.svg)[![Publish](https://github.com/WeTransfer/frame-events/actions/workflows/pusblish.yml/badge.svg)](https://github.com/WeTransfer/frame-events/actions/workflows/publish.yml)
# 🔗 Frame Events

Frame Events is a library for establishing secure parent and child 2-way communication when working with iframes and the `window.postMessage` method.
Frame Events is a communication layer library between the DOM and iframes allowing for secure parent and child 2-way communication using the `window.postMessage` method.

## How it works
[DOCS: Working with Frame Events](./docs/working-with-frame-events.md)

The library consists of two classes, `ParentFrame`, to be instantiated in the parent document and `ChildFrame`, to be run in the embedded document. They both make use of the `Window.postMessage()` method and the `onmessage` event handler.
# Mechanism

When a ParentFrame instance defines an interface it sends a ready event to the ChildFrame instance in the embedded document. When the ChildFrame instance receives the ready event it runs the subscriber callback.
Frame Event allows for two documents to communicate with one another. The library needs to exist on both documents and consists of two classes that needs be instantiated in each document accordingly. A `ParentFrame` is instantiated in the parent document and a `ChildFrame` is instantiated in the embedded document. Frame events make use of the `Window.postMessage()` method and the `onmessage` event handler to broker messages between.

## Using ParentFrame
![Subscriber Callback](./docs/images/subscriber_callback.svg "Subscriber Callback Diagram")

```typescript
new ParentFrame(options);
```

### Options

| Name | Type | |
| --------- | ------------------- | ---------- |
| child | `HTMLIFrameElement` | `required` |
| methods | `object` | |
| listeners | `string[]` | |
| scripts | `string[]` | |

#### child

A child is a `HTMLIFrameElement` that is embedding a document with a ChildFrame instance into the parent document. This iframe must be attached to the DOM and ready to receive events.

When building your iframe source you must specify the parent origin in order to establish a secure connection.

```html
<iframe
src="https://example.com/embedded-document/index.html?_origin=http://parentorigin&_placement=myPlacement"
></iframe>
```

#### methods
Parent document:
- ParentFrame instance initiated
- On iframe load it sends the ready event (or errors)

This is an object with methods that can be fired by the embedded document. When defining method make sure you:
Embedded document:
- ChildFrame instance initiated with a subscriber callback
- On receiving a parent ready event:
- Register methods and listeners
- Add 3rd party scripts
- Fire Subscriber callback

- Don't use any reserved words like `ready`.
- Add descriptive meaningful function names, they will later be exposed.
- By design, the methods provided can only take one parameter.
Events are sent two way, parent frame to child frame and child frame to parent frame.

#### listeners
![Event Flow](./docs/images/event_flow.svg "Event FLow Diagram")
Parent document

Listeners is an array of event names that you are opening for subscription in the embedded document.
## Example Project

#### scripts
An example is included in the project in the `/example` folder. Run the following command to see it in action:

An array of html script tags that you want to ad to the embedded document head.

## Using ChildFrame

```typescript
new ChildFrame(myCallbackMethod);
```bash
yarn start:demo
```

### Options

| Name | Type | | |
| -------- | ---------- | ---------- | ------------------------------------------- |
| callback | `function` | `required` | Fires when the parent sends the ready event |
Go to `http://localhost:3030` to see the demo app.

#### callback
![Example](./docs/images/example.png "Example")

A function that will execute when the ChildFrame instance gets the ready signal from the parent frame. This function takes as an argument all event names you can listen to and every command you can execute.
## Example Code

## Example

In the main document:
In the parent document:

```typescript
const state = {
counter: 0,
};
const myAPI = new ParentFrame({
child: document.querySelector('iframe'),
child: document.querySelector("iframe"),
methods: {
updateCounter: function () {
state.counter = state.counter++;
this.send('counterUpdated', {
state.counter++;
this.send("counterUpdated", {
counter: state.counter,
});
},
},
listeners: ['counterUpdated'],
listeners: ["counterUpdated"],
scripts: ['<script src=""></script>', '<script src=""></script>'],
});
```
Expand All @@ -109,26 +80,13 @@ const myChildAPI = new ChildFrame(function (data) {
myChildAPI.listeners.counterUpdated((event) => {});

// Fire commands
document.querySelector('button').addEventListener('click', function () {
document.querySelector("button").addEventListener("click", function () {
myChildAPI.run.updateCounter();
});
});
```

## Known Issues

- IntelliSense won't work due to how we add the methods to the namespace.

## Build

```
yarn build
```

## Running unit tests

Run `yarn test` to execute the unit tests via [Jest](https://jestjs.io).

## Running unit tests with coverage
# License
Created by WeTransfer.

Run `yarn test:coverage` to execute the unit tests with coverage via [Jest](https://jestjs.io).
Frame Events is licensed using the The Hippocratic License see [LICENSE.md](./LICENSE.md).
77 changes: 0 additions & 77 deletions docs/event_flow.drawio

This file was deleted.

4 changes: 4 additions & 0 deletions docs/images/event_flow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/images/subscriber_callback.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading