b2g/components/SystemAppProxy.jsm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 'use strict';
     7 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
     9 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
    10 Cu.import('resource://gre/modules/Services.jsm');
    12 this.EXPORTED_SYMBOLS = ['SystemAppProxy'];
    14 let SystemAppProxy = {
    15   _frame: null,
    16   _isReady: false,
    17   _pendingEvents: [],
    18   _pendingListeners: [],
    20   // To call when a new system app iframe is created
    21   registerFrame: function (frame) {
    22     this._isReady = false;
    23     this._frame = frame;
    25     // Register all DOM event listeners added before we got a ref to the app iframe
    26     this._pendingListeners
    27         .forEach((args) =>
    28                  this.addEventListener.apply(this, args));
    29     this._pendingListeners = [];
    30   },
    32   // To call when it is ready to receive events
    33   setIsReady: function () {
    34     if (this._isReady) {
    35       Cu.reportError('SystemApp has already been declared as being ready.');
    36     }
    37     this._isReady = true;
    39     // Dispatch all events being queued while the system app was still loading
    40     this._pendingEvents
    41         .forEach(([type, details]) =>
    42                  this._sendCustomEvent(type, details));
    43     this._pendingEvents = [];
    44   },
    46   /*
    47    * Common way to send an event to the system app.
    48    *
    49    * // In gecko code:
    50    *   SystemAppProxy.sendCustomEvent('foo', { data: 'bar' });
    51    * // In system app:
    52    *   window.addEventListener('foo', function (event) {
    53    *     event.details == 'bar'
    54    *   });
    55    */
    56   _sendCustomEvent: function systemApp_sendCustomEvent(type, details) {
    57     let content = this._frame ? this._frame.contentWindow : null;
    59     // If the system app isn't ready yet,
    60     // queue events until someone calls setIsLoaded
    61     if (!this._isReady || !content) {
    62       this._pendingEvents.push([type, details]);
    63       return null;
    64     }
    66     let event = content.document.createEvent('CustomEvent');
    68     let payload;
    69     // If the root object already has __exposedProps__,
    70     // we consider the caller already wrapped (correctly) the object.
    71     if ('__exposedProps__' in details) {
    72       payload = details;
    73     } else {
    74       payload = details ? Cu.cloneInto(details, content) : {};
    75     }
    77     event.initCustomEvent(type, true, false, payload);
    78     content.dispatchEvent(event);
    80     return event;
    81   },
    83   // Now deprecated, use sendCustomEvent with a custom event name
    84   dispatchEvent: function systemApp_sendChromeEvent(details) {
    85     return this._sendCustomEvent('mozChromeEvent', details);
    86   },
    88   // Listen for dom events on the system app
    89   addEventListener: function systemApp_addEventListener() {
    90     let content = this._frame ? this._frame.contentWindow : null;
    91     if (!content) {
    92       this._pendingListeners.push(arguments);
    93       return false;
    94     }
    96     content.addEventListener.apply(content, arguments);
    97     return true;
    98   },
   100   removeEventListener: function systemApp_removeEventListener(name, listener) {
   101     let content = this._frame ? this._frame.contentWindow : null;
   102     if (content) {
   103       content.removeEventListener.apply(content, arguments);
   104     } else {
   105       let idx = this._pendingListeners.indexOf(listener);
   106       if (idx != -1) {
   107         this._pendingListeners.splice(idx, 1);
   108       }
   109     }
   110   }
   112 };
   113 this.SystemAppProxy = SystemAppProxy;

mercurial