Broadcasting is a tried and trusted model of …
- information distribution
 - entertainment distribution
 
… and if you add in “listeners who can respond” (perhaps named and the broadcaster can re-respond) you can add …
- feedback
 - collaboration
 - sharing
 
… into the mix. Well, today, we have a Broadcast Channel API idea where same device, same web browser users can subscribe to a Broadcast Channel and join into postMessage() inspired functionality of this ilk.
<html>
<head>
<title>Broadcast API Usage - RJM Programming - July, 2022 ... thanks to https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API</title>
</head>
<body>
<style>
  td { vertical-align: top; }
  #ta { width: 98%; background-color: yellow; }
  #tab { width: 98%; background-color: lightblue; }
</style>
<table border=20 style='width:100%;'>
<tr><th contenteditable=true id=bname>Broadcaster</th><th contenteditable=true id=lname>Listener</th></tr>
<tr><td id=blist>
<input style='width:100%;' id=itab type=text placeholder='RJM Programming Broadcast Channel Name of yours' value='' onblur='newone(this);'></input>
<textarea id=tab placeholder='' value='' onblur='sthis(this);' rows=5 cols=80></textarea>
</td>
<td id=btextarea>
<input id=ita style='width:100%;' type=text placeholder='RJM Programming Broadcast Channel Name of broadcaster to subscribe to' value='' onblur='onenew(this);'></input>
<textarea id=ta onblur='sthis(this);' placeholder='' value='' rows=5 cols=80></textarea>
</td></tr>
</table>
<script type='text/javascript'>
  var lastmsg='';
  let ourbc=null;
  let yourbc=null;
  let pbc=null;
  let bc=null;
  var wois=null;
 
  var ebc=location.search.split('bc=')[1] ? decodeURIComponent(location.search.split('bc=')[1].split('&')[0]).replace(/\+/g,' ') : "";
  if (ebc.trim() != '') {
    //const bc=null;
    document.getElementById('itab').placeholder=ebc;
    document.getElementById('ita').placeholder=ebc;
    document.getElementById('itab').value='';
    document.getElementById('ita').value='';
    document.getElementById('itab').onblur=function(event) { event.target.value=ebc; }
    document.getElementById('ita').onblur=function(event) { event.target.value=ebc; }
    document.getElementById('itab').setAttribute('readonly',true);
    document.getElementById('tab').setAttribute('readonly',true);
    document.getElementById('tab').style.display='none';
    yourbc = new BroadcastChannel(ebc);
    yourbc.onmessage = event => {
      if (minussc(event.data) != lastmsg) {
        //alert('in with msg=' + event.data);
        //document.getElementById('ta').value+=String.fromCharCode(10) + event.data.replace(lastmsg, '');
        document.getElementById('ta').value=String.fromCharCode(10) + event.data; //.replace(lastmsg, '');
        document.getElementById('ta').title='' + new Date();
        document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));
        document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));
        if (yourbc) {
          //yourbc.postMessage(document.getElementById('lname').innerHTML + ': ' + minussc(event.data)); //.replace(lastmsg, ''));
          yourbc.postMessage(event.data); //.replace(lastmsg, ''));
          window.opener.andback(); // wois.focus();
        }
        lastmsg=minussc(event.data);
      }
    };
    wois=window.opener;
  }
 
  function andback() {
    //alert('Am back');
    window.focus();
  }
 
  function oureval(inv) {
    var tabi=document.getElementById('tab').value.split(String.fromCharCode(10));
    var tai=document.getElementById('ta').value.split(String.fromCharCode(10));
    return Math.max(eval(2 + eval('' + tabi.length)), eval(2 + eval('' + tai.length)));
  }
  function newone(iv) {
   if (iv.value.trim() != '') {
    // Connection to a broadcast channel
    //if (ourbc) {
    //  ourbc.close();
    //}
    //const bc = new BroadcastChannel(iv.value);
    bc = new BroadcastChannel(iv.value);
    pbc=bc;
    ourbc=bc;
    document.getElementById('ita').setAttribute('readonly',true);
    document.getElementById('ta').setAttribute('readonly',true);
    document.getElementById('ta').style.display='none';
    ebc=iv.value;
    document.getElementById('itab').placeholder=ebc;
    document.getElementById('ita').placeholder=ebc;
    document.getElementById('itab').value='';
    document.getElementById('ita').value='';
    document.getElementById('itab').onblur=function(event) { event.target.value=ebc; }
    document.getElementById('ita').onblur=function(event) { event.target.value=ebc; }
    bc.onmessage = event => {
      if (minussc(event.data) != lastmsg) {
        //document.getElementById('tab').value+=String.fromCharCode(10) + event.data.replace(lastmsg, '');
        document.getElementById('tab').value=String.fromCharCode(10) + event.data; //.replace(lastmsg, '');
        document.getElementById('tab').title='' + new Date();
        document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));
        document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));
        if (bc) {
          //bc.postMessage(document.getElementById('bname').innerHTML + ': ' + minussc(event.data)); //.replace(lastmsg, ''));
          bc.postMessage(event.data); //.replace(lastmsg, ''));
          wois.focus();
        }
        lastmsg=minussc(event.data);
      }
    };
    wois=window.open(document.URL.split('#')[0].split('?')[0] + '?bc=' + encodeURIComponent(iv.placeholder), '_blank');
   }
  }
 
  function onenew(iv) {
    yourbc = new BroadcastChannel(iv.value);
    yourbc.onmessage = event => {
      if (minussc(event.data) != lastmsg) {
        //document.getElementById('tab').value+=String.fromCharCode(10) + event.data.replace(lastmsg, '');
        document.getElementById('tab').value=String.fromCharCode(10) + event.data; //.replace(lastmsg, '');
        document.getElementById('tab').title='' + new Date();
        document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));
        document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));
        if (ourbc) {
          //ourbc.postMessage(document.getElementById('bname').innerHTML + ': ' + minussc(event.data)); //.replace(lastmsg, ''));
          ourbc.postMessage(event.data); //.replace(lastmsg, ''));
          wois.focus();
        }
        lastmsg=minussc(event.data);
      }
    };
  }
 
  function minussc(insa) {
    if (insa.indexOf(': ') != -1) {
      return insa.replace(insa.split(': ')[0] + ': ','');
    }
    return insa;
  }
 
  function sthis(iv) {
    if (iv.value.trim() != '') {
    if (yourbc && !pbc) {
      yourbc.postMessage(document.getElementById('lname').innerHTML + ': ' + minussc(iv.value));
      document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));
      document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));
      iv.placeholder+=String.fromCharCode(10) + iv.value;
      iv.value='';
    } else if (bc) {
      //alert('at broadcaster with msg=' + iv.value);
      //bc=newone(document.getElementById('itab'));
      bc.postMessage(document.getElementById('bname').innerHTML + ': ' + minussc(iv.value));
      document.getElementById('ta').rows='' + oureval(3 + eval('' + document.getElementById('ta').rows));
      document.getElementById('tab').rows='' + oureval(3 + eval('' + document.getElementById('tab').rows));
      iv.placeholder+=String.fromCharCode(10) + iv.value;
      iv.value='';
    }
    }
  }
</script>
</body>
</html>
… as a first draft “proof of concept” broadcast_api_test.html Broadcast API web application you can try for yourself.
If this was interesting you may be interested in this too.
                    								

