Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 let Ci = Components.interfaces;
6 let Cu = Components.utils;
8 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
9 Cu.import('resource://gre/modules/Services.jsm');
10 Cu.import('resource://gre/modules/DOMRequestHelper.jsm');
12 XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen',
13 'resource://gre/modules/GlobalSimulatorScreen.jsm');
15 let DEBUG_PREFIX = 'SimulatorScreen.js - ';
16 function debug() {
17 //dump(DEBUG_PREFIX + Array.slice(arguments) + '\n');
18 }
20 function fireOrientationEvent(window) {
21 let e = new window.Event('mozorientationchange');
22 window.screen.dispatchEvent(e);
23 }
25 function hookScreen(window) {
26 let nodePrincipal = window.document.nodePrincipal;
27 let origin = nodePrincipal.origin;
28 if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
29 Cu.reportError('deny mozLockOrientation:' + origin + 'is not installed');
30 return;
31 }
33 let screen = window.wrappedJSObject.screen;
35 screen.mozLockOrientation = function (orientation) {
36 debug('mozLockOrientation:', orientation, 'from', origin);
38 // Normalize and do some checks against orientation input
39 if (typeof(orientation) == 'string') {
40 orientation = [orientation];
41 }
43 function isInvalidOrientationString(str) {
44 return typeof(str) != 'string' ||
45 !str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/);
46 }
47 if (!Array.isArray(orientation) ||
48 orientation.some(isInvalidOrientationString)) {
49 Cu.reportError('Invalid orientation "' + orientation + '"');
50 return false;
51 }
53 GlobalSimulatorScreen.lock(orientation);
55 return true;
56 };
58 screen.mozUnlockOrientation = function() {
59 debug('mozOrientationUnlock from', origin);
60 GlobalSimulatorScreen.unlock();
61 return true;
62 };
64 Object.defineProperty(screen, 'width', {
65 get: function () GlobalSimulatorScreen.width
66 });
67 Object.defineProperty(screen, 'height', {
68 get: function () GlobalSimulatorScreen.height
69 });
70 Object.defineProperty(screen, 'mozOrientation', {
71 get: function () GlobalSimulatorScreen.mozOrientation
72 });
73 }
75 function SimulatorScreen() {}
76 SimulatorScreen.prototype = {
77 classID: Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'),
78 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
79 Ci.nsISupportsWeakReference]),
80 _windows: new Map(),
82 observe: function (subject, topic, data) {
83 let windows = this._windows;
84 switch (topic) {
85 case 'profile-after-change':
86 Services.obs.addObserver(this, 'document-element-inserted', false);
87 Services.obs.addObserver(this, 'simulator-orientation-change', false);
88 Services.obs.addObserver(this, 'inner-window-destroyed', false);
89 break;
91 case 'document-element-inserted':
92 let window = subject.defaultView;
93 if (!window) {
94 return;
95 }
97 hookScreen(window);
99 var id = window.QueryInterface(Ci.nsIInterfaceRequestor)
100 .getInterface(Ci.nsIDOMWindowUtils)
101 .currentInnerWindowID;
102 windows.set(id, window);
103 break;
105 case 'inner-window-destroyed':
106 var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
107 windows.delete(id);
108 break;
110 case 'simulator-orientation-change':
111 windows.forEach(fireOrientationEvent);
112 break;
113 }
114 }
115 };
117 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]);