@plattar/context-messenger

Context Messenger framework for cross-iframe communication (https://www.plattar.com)


Keywords
plattar, npm, ar, augmented, reality, augmentedreality, augmented-reality, context, messenger, context-messenger, function, functioncall
License
Apache-2.0
Install
npm install @plattar/context-messenger@1.113.1

Documentation

Plattar Logo

install size Minified MinZipped NPM Codacy Badge License

context-messenger allows defining and calling functions and variables across multiple iframes.

Quick Use

// Minified Version ES2015 & ES2019 (Latest)
https://cdn.jsdelivr.net/npm/@plattar/context-messenger/build/es2015/plattar-context-messenger.min.js
https://cdn.jsdelivr.net/npm/@plattar/context-messenger/build/es2019/plattar-context-messenger.min.js

// Standard Version ES2015 & ES2019 (Latest)
https://cdn.jsdelivr.net/npm/@plattar/context-messenger/build/es2015/plattar-context-messenger.js
https://cdn.jsdelivr.net/npm/@plattar/context-messenger/build/es2019/plattar-context-messenger.js

Installation

  • Install using npm
npm install @plattar/context-messenger

Examples

How to execute functions from an iframe on the parent page

  • Define a function in the parent page that executes and returns a result

This function will then become available to be executed from other context-messenger frameworks from either the parent or child iframes.

Plattar.messenger.self.sum = (arg1, arg2) => {
  return arg1 + arg2;
};

From within the iframe itself that has the context-messenger framework, the above function can be executed as follows. Notice that the function is executed asynchronously and handled via a Promise chain.

Plattar.messenger.parent.sum(1,4).then((result) => {
  console.log(result); // this will print 5
}).catch((err) => {
  console.error(err);
});
  • Define a function in the current context that executes and returns a result asynchronously

The context-messenger framework can also handle asynchronous functions using Promises. Below we define a function that performs a sum asynchronously.

Plattar.messenger.self.sumDelayed = (arg1, arg2) => {
  // perform the sum after 3 seconds and return the result
  return new Promise((accept, reject) => {
    setTimeout(() => {
      accept(arg1 + arg2);
    }, 3000);
  });
};

From within an iframe itself that has the context-messenger framework, the above function can be executed as follows. Notice that nothing changes with the function execution and the results are still handled using a Promise chain. In this instance, the Promise will execute after 3 seconds.

Plattar.messenger.parent.sumDelayed(1,4).then((result) => {
  console.log(result); // this will print 5 after 3 seconds
}).catch((err) => {
  console.error(err);
});

How to execute functions from the parent page inside of the iframe

  • Define an iframe on the parent page that has the context-messenger framework and provide some ID
<iframe id="frame1" src="./your-nested-page.html"></iframe>
  • Define a function inside your-nested-page.html file using the context-messenger that returns the page background color
Plattar.messenger.self.getBackgroundColor = () => {
  return document.body.style.backgroundColor;
};
  • To execute the function inside of frame1 do the following
Plattar.messenger.frame1.getBackgroundColor().then((result) => {
  console.log(result); // prints the background color of the iframe
}).catch((err) => {
  console.error(err);
});

context-messenger is designed to automatically initialise itself from other instances of context-messenger that exist inside iframes and/or the parent page. Because this process is asynchronous, sometimes the iframe is not ready before calling its functions. To fix this, listen for the onload event for your desired iframe as follows.

Plattar.messenger.onload("frame1", () => {
  // iframe with ID of frame1 has finished loading. If this is not called
  // then the iframe might not have a Messenger framework
});

The same can be done for the parent page to ensure its loaded before iframes can call parent functions

Plattar.messenger.onload("parent", () => {
  // the parent page has finished loading. If this is not called
  // then the page might not have a parent page or the parent does not
  // have a Messenger framework
});

How to execute functions from the parent page inside of multiple iframes

  • Define multiple iframes on the parent page that has the context-messenger framework and provide some ID
<iframe id="frame1" src="./your-nested-page.html"></iframe>
<iframe id="frame2" src="./your-nested-page.html"></iframe>
<iframe id="frame3" src="./your-nested-page.html"></iframe>
  • Define a function inside your-nested-page.html file using the context-messenger that returns the page background color
Plattar.messenger.self.getBackgroundColor = () => {
  return document.body.style.backgroundColor;
};

Sometimes its easier to just call the same function on all available iframes on the page at the same time. The context-messenger provides a broadcast functinality that can handle the function call and resolution for you.

// broadcast will call getBackgroundColor() on frame1, frame2 and frame3 automatically.
// the Promise will resolve when all iframes resolve or fail the function call
Plattar.messenger.broadcast.getBackgroundColor().then((results) => {
  // results contains the returned data from all 3 iframes
  results.forEach((result) => {
    if (result.status == "fulfilled") {
      console.log(result.value); // prints the returned color 
    }
  });
});

For more details on how this is handled see Promise.allSettled

How to store and read variables from iframes

Storing of variables is done using context-messenger memory module. All variables are available to be accessed in all contexts. Note that the memory module does not allow storing functions. Use messenger module for that.

  • To store a temporary variable use the following. Temporary variables are not persistent and will be cleared when the javascript context ends.
Plattar.memory.temp.my_variable = "hello world!";
  • Access the variable as follows from any context that has context-messenger
console.log(Plattar.memory.temp.my_variable); // prints hello world!
  • To store a persistent variable use the following. Persistent memory uses localStorage behind the scenes.
Plattar.memory.perm.my_variable = "hello world!";
  • Access the variable as follows from any context that has context-messenger
console.log(Plattar.memory.perm.my_variable); // prints hello world!

How to watch for variable changes

context-messenger memory module provides a watch function that allows detecting when the variable has changed.

  • Watch a temp or perm variable example
// watch temp variable changes for my_temp_variable
Plattar.memory.temp.watch("my_temp_variable", (oldVar, newVar) => {
  console.log("old variable was " + oldVar);
  console.log("new variable was " + newVar);
});

// watch perm variable changes for my_perm_variable
Plattar.memory.perm.watch("my_perm_variable", (oldVar, newVar) => {
  console.log("old variable was " + oldVar);
  console.log("new variable was " + newVar);
});

// set initial variables
Plattar.memory.temp.my_temp_variable = "hello world!";
Plattar.memory.perm.my_perm_variable = "hello world!";

// initiate a variable change
Plattar.memory.temp.my_temp_variable = "hello world again!";
Plattar.memory.perm.my_perm_variable = "hello world again!";