b2g/components/SimulatorScreen.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/b2g/components/SimulatorScreen.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,117 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +let Ci = Components.interfaces;
     1.9 +let Cu = Components.utils;
    1.10 +
    1.11 +Cu.import('resource://gre/modules/XPCOMUtils.jsm');
    1.12 +Cu.import('resource://gre/modules/Services.jsm');
    1.13 +Cu.import('resource://gre/modules/DOMRequestHelper.jsm');
    1.14 +
    1.15 +XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen',
    1.16 +                                  'resource://gre/modules/GlobalSimulatorScreen.jsm');
    1.17 +
    1.18 +let DEBUG_PREFIX = 'SimulatorScreen.js - ';
    1.19 +function debug() {
    1.20 +  //dump(DEBUG_PREFIX + Array.slice(arguments) + '\n');
    1.21 +}
    1.22 +
    1.23 +function fireOrientationEvent(window) {
    1.24 +  let e = new window.Event('mozorientationchange');
    1.25 +  window.screen.dispatchEvent(e);
    1.26 +}
    1.27 +
    1.28 +function hookScreen(window) {
    1.29 +  let nodePrincipal = window.document.nodePrincipal;
    1.30 +  let origin = nodePrincipal.origin;
    1.31 +  if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
    1.32 +    Cu.reportError('deny mozLockOrientation:' + origin + 'is not installed');
    1.33 +    return;
    1.34 +  }
    1.35 +
    1.36 +  let screen = window.wrappedJSObject.screen;
    1.37 +
    1.38 +  screen.mozLockOrientation = function (orientation) {
    1.39 +    debug('mozLockOrientation:', orientation, 'from', origin);
    1.40 +
    1.41 +    // Normalize and do some checks against orientation input
    1.42 +    if (typeof(orientation) == 'string') {
    1.43 +      orientation = [orientation];
    1.44 +    }
    1.45 +
    1.46 +    function isInvalidOrientationString(str) {
    1.47 +      return typeof(str) != 'string' ||
    1.48 +        !str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/);
    1.49 +    }
    1.50 +    if (!Array.isArray(orientation) ||
    1.51 +        orientation.some(isInvalidOrientationString)) {
    1.52 +      Cu.reportError('Invalid orientation "' + orientation + '"');
    1.53 +      return false;
    1.54 +    }
    1.55 +
    1.56 +    GlobalSimulatorScreen.lock(orientation);
    1.57 +
    1.58 +    return true;
    1.59 +  };
    1.60 +
    1.61 +  screen.mozUnlockOrientation = function() {
    1.62 +    debug('mozOrientationUnlock from', origin);
    1.63 +    GlobalSimulatorScreen.unlock();
    1.64 +    return true;
    1.65 +  };
    1.66 +
    1.67 +  Object.defineProperty(screen, 'width', {
    1.68 +    get: function () GlobalSimulatorScreen.width
    1.69 +  });
    1.70 +  Object.defineProperty(screen, 'height', {
    1.71 +    get: function () GlobalSimulatorScreen.height
    1.72 +  });
    1.73 +  Object.defineProperty(screen, 'mozOrientation', {
    1.74 +    get: function () GlobalSimulatorScreen.mozOrientation
    1.75 +  });
    1.76 +}
    1.77 +
    1.78 +function SimulatorScreen() {}
    1.79 +SimulatorScreen.prototype = {
    1.80 +  classID:         Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'),
    1.81 +  QueryInterface:  XPCOMUtils.generateQI([Ci.nsIObserver,
    1.82 +                                          Ci.nsISupportsWeakReference]),
    1.83 +  _windows: new Map(),
    1.84 +
    1.85 +  observe: function (subject, topic, data) {
    1.86 +    let windows = this._windows;
    1.87 +    switch (topic) {
    1.88 +      case 'profile-after-change':
    1.89 +        Services.obs.addObserver(this, 'document-element-inserted', false);
    1.90 +        Services.obs.addObserver(this, 'simulator-orientation-change', false);
    1.91 +        Services.obs.addObserver(this, 'inner-window-destroyed', false);
    1.92 +        break;
    1.93 +
    1.94 +      case 'document-element-inserted':
    1.95 +        let window = subject.defaultView;
    1.96 +        if (!window) {
    1.97 +          return;
    1.98 +        }
    1.99 +
   1.100 +        hookScreen(window);
   1.101 +
   1.102 +        var id = window.QueryInterface(Ci.nsIInterfaceRequestor)
   1.103 +                       .getInterface(Ci.nsIDOMWindowUtils)
   1.104 +                       .currentInnerWindowID;
   1.105 +        windows.set(id, window);
   1.106 +        break;
   1.107 +
   1.108 +      case 'inner-window-destroyed':
   1.109 +        var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
   1.110 +        windows.delete(id);
   1.111 +        break;
   1.112 +
   1.113 +      case 'simulator-orientation-change':
   1.114 +        windows.forEach(fireOrientationEvent);
   1.115 +        break;
   1.116 +    }
   1.117 +  }
   1.118 +};
   1.119 +
   1.120 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]);

mercurial