title: Communication between injected iframe and content script -- message passing via background page
body: <p>I am injecting an <code>iframe</code> in a <code>tab</code>. Now inside the the <code>iframe</code>, based on user's actions, I need to show some <code>error/warning/success notifications</code>. However I want to display these notifications in the <code>tab</code> not in <code>iframe</code>. So I need to communicate between <code>iframe</code> and <code>content script</code>. Now these <code>notifications</code> are dynamic based on user's actions so I thought of <code>message passing</code> between <code>iframe</code> and <code>content script</code> via <code>background page</code>.</p>
  
  <p>So what i have done is send messages from <code>iframe</code> to <code>background</code>. Now both <code>background page</code> and <code>content script</code> listens to these messages but only <code>background page</code> is able to receive them. On receiving messages it reflects them back to <code>sender tab</code>. Now <code>content script</code> can receive these messages as they are sent from <code>background page</code>.</p>
  
  <p>Now I tried the same using <code>custom events</code> but it didn't work. </p>
  
  <p><strong>But i would like to know any other method which is more efficient than what i am doing??</strong></p>
  
  <p><strong>EDIT</strong> : Here's the relevant code</p>
  
  <p><strong>iframe.js:</strong></p>
  
  <pre><code>    $scope.hideFrame = function(){                                        
         sendMessageToBackground("hideFrame");
      };
  
       $scope.checkIfFormValid = function(){
         if(!($scope.taskName === "" || $scope.group.selectedGroup === null )){
            $scope.addTask();
          }
          else{
            sendMessageToBackground("invalidForm");
          }
       };
  
      function sendMessageToBackground(msg){
         chrome.runtime.sendMessage({type: msg});
      }
  </code></pre>
  
  <p><strong>background.js:</strong></p>
  
  <pre><code>chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
     switch (request.type){
  
                  case "hideFrame":
                     chrome.tabs.sendMessage(sender.tab.id,{type:"hideFrame"});
                     break;
                  case "invalidForm":
                     chrome.tabs.sendMessage(sender.tab.id,{type:"invalidForm"});
                     break;
  
              }      
   });
  </code></pre>
  
  <p><strong>content.js:</strong></p>
  
  <pre><code>  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
                  switch (request.type){
                       case "invalidForm":
                           var n = noty({
                                          text        : ' Please fill all details',
                                          type        : 'error',
                                          layout      : 'topRight',
                                          timeout     :  10000,
                                          theme       : 'defaultTheme'
                                      });
                          break;
  
                      case "hideFrame":
                        $("#isolatedFrame").hide();
                        break;
                  }      
      });
  </code></pre>
  
  <p><strong>Using <code>window.parent.postMessage</code>(not working)</strong>:</p>
  
  <p><strong>iframe.js:</strong></p>
  
  <pre><code> function sendMessageToContent(msg){
               // chrome.runtime.sendMessage({type: msg});
               window.parent.postMessage({ type: "fromFrame", message: msg }, "*");
              }
  </code></pre>
  
  <p><strong>content.js:</strong></p>
  
  <pre><code>window.addEventListener("message", function(event) {
  
    if (event.source != window)
      return;
  
    if (event.data.type &amp;&amp; (event.data.type == "fromFrame")) {
      console.log("Content script received: " + event.data.message);
  
    }
  }, false);
  </code></pre>
  
  <p>Also, when i add a <code>breakpoint</code> at <code>window.parent.postMessage({ type: "fromFrame", message: msg }, "*");</code> and try to see <code>window.parent</code> object , <code>inspected target</code> is disconnected. I don't why this is happening??</p>