What is the best way to directly send a message from a panel to a page-mod's content script?

When working with a code snippet in a Firefox addon like the one below:

var pagemod = PageMod({
    include: ['*'],
    contentScriptFile: [data.url('content.js')]
});

panel = require("sdk/panel").Panel({
  width: 322,
  height: 427,
  contentURL: data.url("main.html"),
  include:["http://*/*","https://*/*"],
  contentScriptFile: [data.url('panel.js')]  
});

I recently came across some example code in a Chrome extension where they utilize

window.parent.postMessage(message, "*")
to send messages and
window.addEventListener("message",function (e) {//do something}
to receive them. How can I establish direct communication for message passing from "panel.js" to "content.js" within a Firefox addon?

Answer №1

The solution concept closely resembles the approach outlined in this particular answer:

  1. Keep track of message ports for each tab.
  2. When sending a message, dispatch it to all recorded ports.

In order to manage a list of ports effectively, the following code snippet is implemented:

var ports = [];
var pagemod = PageMod({
    include: ['*'],
    contentScriptFile: [data.url('content.js')],
    onAttach: function(worker) {
        ports.push(worker.port);
        worker.on('detach', function() {
            var index = ports.indexOf(worker.port);
            if (index !== -1) ports.splice(index, 1);
        });
    }
});

Now, to send a message from panel.js, simply utilize:

// panel.js
self.port.emit('message-to-tabs', 'example message');

The handling of this message must occur in the main script post creation of the panel:

panel = require('sdk/panel').Panel({
    width: 322,
    height: 427,
    contentURL: data.url('main.html'),
    include: ['http://*/*', 'https://*/*'],
    contentScriptFile: [data.url('panel.js')]  
});
panel.port.on('message-to-tabs', function(message) {
    for (var i=0; i<ports.length; i++) {
        ports[i].emit('message-to-tab', message);
    }
});

Within the content script of the tab (content.js), you can listen for this event and process it accordingly:

self.port.on('message-to-tab', function(message) {
    // Handle message appropriately
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Storing audio files in Firebase Cloud Database and displaying them in React js + Dealing with an infinite loop problem

Lately, I've been encountering a persistent issue that has proven to be quite challenging. Any assistance would be greatly appreciated. Thank you in advance. The objective is to create a form that allows for the easy addition of new documents to the ...

Transitioning away from bundled Javascript for local debugging

My current tasks on the gulpfile.js for my frontend app involve a serve task that handles the following: Processing less files Bundling all javascripts into dist/bundle.js Uglifying dist/bundle.js However, this setup made local debugging difficult. To a ...

Uncovering the Image Orientation in Angular: Is it Possible to Determine the Direction Post-view or Upon Retrieval from Database?

I am currently working on creating centered and cropped thumbnails for images retrieved from a database. I came across some helpful information on how to achieve this: The resource I found is written for JavaScript, but I am using Angular 7. I am facing d ...

I'm having trouble getting my if statement to function properly with a random number

I'm currently working on creating a natural disaster sequence for my game, and I'm using Math.random to simulate different outbreak scenarios. However, I've encountered an issue at the end of my code where an if statement is supposed to trig ...

Vue router is unable to render or mount the component at the root path

I am currently working on a webpage using vue, vue-router, and laravel. I have encountered an issue where the Home component is not being rendered in the router-view when I access localhost/myproject/public_html/. However, if I click on the router link to ...

Converting UK DateTime to GMT time using Angular

I am currently working on an angular project that involves displaying the start and end times of office hours in a table. For instance, the office operates from 8:30 AM to 5:30 PM. This particular office has branches located in the UK and India. Since u ...

What is the proper way to structure the ng-options syntax in AngularJS?

I received an array from a REST service and I am attempting to generate a dropdown menu based on that data. Check out the jsfiddle example here $scope.reasons = [{ "languageLanguageId": { "languageId": 1, "lastUpdate": "2015-05-08T11:14:00+03:00" ...

Each time I attempt to update my profile on the web application, I receive this notification

Working on creating a web app using react, redux, and node for managing profile data. I have a function that controls both creation and editing of profiles. The creation works fine, but I encounter an error message when trying to edit. I've reviewed m ...

Is there a way to create a universal getter/setter for TypeScript classes?

One feature I understand is setting getters and setters for individual properties. export class Person { private _name: string; set name(value) { this._name = value; } get name() { return this._name; } } Is there a w ...

Tips for handling catch errors in fetch POST requests in React Native

I am facing an issue with handling errors when making a POST request in React Native. I understand that there is a catch block for network connection errors, but how can I handle errors received from the response when the username or password is incorrec ...

Implementing a return of a view from a Laravel controller function after an AJAX request

I'm currently working on a bookstore project where users can add books to their cart. Users have the option to select multiple books and add them to the cart. When the user clicks on the Add to Cart button, I store the IDs of the selected books in a J ...

A guide on effectively utilizing the Map datatype in JavaScript

Recently, I've started delving into the world of es6 Map due to its unique features, but I have some reservations regarding pure operations. For example, when removing properties from objects, I usually use the following function: function cloneOmit ...

change visibility:hidden to visible in a css class using JavaScript

I've put together a list of Game of Thrones characters who might meet their demise (no spoilers included). However, I'm struggling with removing a CSS class as part of my task. Simply deleting the CSS is not the solution I am looking for. I' ...

Implementing a translucent overlay onto a specific HTML section using sidebar.js/jQuery

Searching for a way to enhance the functionality of my website using Sidebar.js, I came across an interesting feature on hypebeast.com. When you click on the three-bar icon, the main container section's opacity changes. How can I achieve this effect? ...

Having trouble saving user input from a form to a database using axios, mongodb, and vue?

I am a beginner in working with Vue and I'm currently facing an issue while trying to submit user input data to my MongoDB using axios. Although the data from the database is displayed on the page, I can't seem to get the form input data to succe ...

No error reported upon trying to render json output

I'm having an issue where the following code is not displaying any output. Can someone help me identify what mistake I might be making? This is the HTML file: <head> <script type = "text/javascript"> function ajax_get_json() { var h ...

Using Angular's filter pipe to search within a nested array

We are attempting to implement an angular pipe for filtering a list of sub-items, with the goal of removing parent items if there are no child items present. Here is the HTML code snippet we are using: <div class="row border-bottom item" *n ...

What is the method for incorporating a timeout in a promise?

After exploring various methods for adding timeouts to promises, it appears that most rely on the setTimeout() function. Here is the formal definition: The setTimeout() function executes a specified function or evaluates an expression after a set number of ...

Managing Dark Mode in Material UI with Redux

Having a React application integrated with Material UI, I encountered an issue with the dark mode functionality. Whenever I attempt to modify the dark mode state on a page where the content is rendered from redux state data, the entire page crashes. It app ...

The expected behavior is not displayed when using Async.waterfall within a promise queue

In our software implementation, we have utilized a promise queue feature using the q library. The sequence of functions is structured as follows: PQFn1 -(then)- PQFn2 - .... Within PQFn1, an array of values is passed to a callback function implemented wi ...