B2G/gecko/toolkit/components/social/MozSocialAPI.jsm
// Loads mozSocial support functions associated with provider into targetWindow
Loads mozSocial support functions associated with provider into targetWindow
Loads mozSocial support functions associated with provider into targetWindow
function attachToWindow(provider, targetWindow) {
  let origin = provider.origin;
  if (!provider.enabled) {
    throw new Error("MozSocialAPI: cannot attach disabled provider " + origin);
  }
  let targetDocURI = targetWindow.document.documentURIObject;
  if (provider.origin != targetDocURI.prePath) {
    throw new Error("MozSocialAPI: cannot attach " + origin + " to " + targetDocURI.spec);
  }
  var port = provider.getWorkerPort(targetWindow);
  let mozSocialObj = {
    getWorker: {
      enumerable: true,
      configurable: true,
      writable: true,
      value: function() {
        return {
          port: port,
          __exposedProps__: {
            port: "r"
          }
        };
      }
    },
    hasBeenIdleFor: {
      enumerable: true,
      configurable: true,
      writable: true,
      value: function() {
        return false;
      }
    },
    openChatWindow: {
      enumerable: true,
      configurable: true,
      writable: true,
      value: function(toURL, callback) {
        let url = targetWindow.document.documentURIObject.resolve(toURL);
        openChatWindow(getChromeWindow(targetWindow), provider, url, callback);
      }
    },
    openPanel: {
      enumerable: true,
      configurable: true,
      writable: true,
      value: function(toURL, offset, callback) {
        let chromeWindow = getChromeWindow(targetWindow);
        if (!chromeWindow.SocialFlyout)
          return;
        let url = targetWindow.document.documentURIObject.resolve(toURL);
        let fullURL = ensureProviderOrigin(provider, url);
        if (!fullURL)
          return;
        chromeWindow.SocialFlyout.open(fullURL, offset, callback);
      }
    },
    closePanel: {
      enumerable: true,
      configurable: true,
      writable: true,
      value: function(toURL, offset, callback) {
        let chromeWindow = getChromeWindow(targetWindow);
        if (!chromeWindow.SocialFlyout || !chromeWindow.SocialFlyout.panel)
          return;
        chromeWindow.SocialFlyout.panel.hidePopup();
      }
    },
    getAttention: {
      enumerable: true,
      configurable: true,
      writable: true,
      value: function() {
        getChromeWindow(targetWindow).getAttention();
      }
    },
    isVisible: {
      enumerable: true,
      configurable: true,
      get: function() {
        return targetWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                           .getInterface(Ci.nsIWebNavigation)
                           .QueryInterface(Ci.nsIDocShell).isActive;
      }
    }
  };
  let contentObj = Cu.createObjectIn(targetWindow);
  Object.defineProperties(contentObj, mozSocialObj);
  Cu.makeObjectPropsNormal(contentObj);
  targetWindow.navigator.wrappedJSObject.__defineGetter__("mozSocial", function() {
    delete targetWindow.navigator.wrappedJSObject.mozSocial;
    return targetWindow.navigator.wrappedJSObject.mozSocial = contentObj;
  });
  targetWindow.addEventListener("unload", function () {
    schedule(function () { port.close(); });
  });
  let dwu = targetWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils);
  dwu.allowScriptsToClose();
  targetWindow.addEventListener("DOMWindowClose", function _mozSocialDOMWindowClose(evt) {
    let elt = targetWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIWebNavigation)
                .QueryInterface(Ci.nsIDocShell)
                .chromeEventHandler;
    while (elt) {
      if (elt.nodeName == "panel") {
        elt.hidePopup();
        break;
      } else if (elt.nodeName == "chatbox") {
        elt.close();
        break;
      }
      elt = elt.parentNode;
    }
    evt.preventDefault();
  }, true);
}
function attachToWindow ( provider , targetWindow ) { let origin = provider . origin ; if ( ! provider . enabled ) { throw new Error ( "MozSocialAPI: cannot attach disabled provider " + origin ) ; } let targetDocURI = targetWindow . document . documentURIObject ; if ( provider . origin != targetDocURI . prePath ) { throw new Error ( "MozSocialAPI: cannot attach " + origin + " to " + targetDocURI . spec ) ; } var port = provider . getWorkerPort ( targetWindow ) ; let mozSocialObj = { getWorker : { enumerable : true , configurable : true , writable : true , value : function ( ) { return { port : port , __exposedProps__ : { port : "r" } } ; } } , hasBeenIdleFor : { enumerable : true , configurable : true , writable : true , value : function ( ) { return false ; } } , openChatWindow : { enumerable : true , configurable : true , writable : true , value : function ( toURL , callback ) { let url = targetWindow . document . documentURIObject . resolve ( toURL ) ; openChatWindow ( getChromeWindow ( targetWindow ) , provider , url , callback ) ; } } , openPanel : { enumerable : true , configurable : true , writable : true , value : function ( toURL , offset , callback ) { let chromeWindow = getChromeWindow ( targetWindow ) ; if ( ! chromeWindow . SocialFlyout ) return ; let url = targetWindow . document . documentURIObject . resolve ( toURL ) ; let fullURL = ensureProviderOrigin ( provider , url ) ; if ( ! fullURL ) return ; chromeWindow . SocialFlyout . open ( fullURL , offset , callback ) ; } } , closePanel : { enumerable : true , configurable : true , writable : true , value : function ( toURL , offset , callback ) { let chromeWindow = getChromeWindow ( targetWindow ) ; if ( ! chromeWindow . SocialFlyout || ! chromeWindow . SocialFlyout . panel ) return ; chromeWindow . SocialFlyout . panel . hidePopup ( ) ; } } , getAttention : { enumerable : true , configurable : true , writable : true , value : function ( ) { getChromeWindow ( targetWindow ) . getAttention ( ) ; } } , isVisible : { enumerable : true , configurable : true , get : function ( ) { return targetWindow . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIWebNavigation ) . QueryInterface ( Ci . nsIDocShell ) . isActive ; } } } ; let contentObj = Cu . createObjectIn ( targetWindow ) ; Object . defineProperties ( contentObj , mozSocialObj ) ; Cu . makeObjectPropsNormal ( contentObj ) ; targetWindow . navigator . wrappedJSObject . __defineGetter__ ( "mozSocial" , function ( ) { delete targetWindow . navigator . wrappedJSObject . mozSocial ; return targetWindow . navigator . wrappedJSObject . mozSocial = contentObj ; } ) ; targetWindow . addEventListener ( "unload" , function ( ) { schedule ( function ( ) { port . close ( ) ; } ) ; } ) ; let dwu = targetWindow . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIDOMWindowUtils ) ; dwu . allowScriptsToClose ( ) ; targetWindow . addEventListener ( "DOMWindowClose" , function _mozSocialDOMWindowClose ( evt ) { let elt = targetWindow . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIWebNavigation ) . QueryInterface ( Ci . nsIDocShell ) . chromeEventHandler ; while ( elt ) { if ( elt . nodeName == "panel" ) { elt . hidePopup ( ) ; break ; } else if ( elt . nodeName == "chatbox" ) { elt . close ( ) ; break ; } elt = elt . parentNode ; } evt . preventDefault ( ) ; } , true ) ; }
Loads mozSocial support functions associated with provider into targetWindow
Loads mozSocial support functions associated with provider into targetWindow
// Use a method for backwards compat with existing providers, but we // should deprecate this in favor of a simple .port getter. // We do this in a getter, so that we create these objects // only on demand (this is a potential concern, since // otherwise we might add one per iframe, and keep them // alive for as long as the window is alive). // We want to close the port, but also want the target window to be // able to use the port during an unload event they setup - so we // set a timer which will fire after the unload events have all fired. // We allow window.close() to close the panel, so add an event handler for // this, then cancel the event (so the window itself doesn't die) and // close the panel instead. // However, this is typically affected by the dom.allow_scripts_to_close_windows // preference, but we can avoid that check by setting a flag on the window. // preventDefault stops the default window.close() function being called, // which doesn't actually close anything but causes things to get into // a bad state (an internal 'closed' flag is set and debug builds start // asserting as the window is used.). // None of the windows we inject this API into are suitable for this // default close behaviour, so even if we took no action above, we avoid // the default close from doing anything.