michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: let Ci = Components.interfaces; michael@0: let Cu = Components.utils; michael@0: michael@0: Cu.import('resource://gre/modules/XPCOMUtils.jsm'); michael@0: Cu.import('resource://gre/modules/Services.jsm'); michael@0: Cu.import('resource://gre/modules/DOMRequestHelper.jsm'); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen', michael@0: 'resource://gre/modules/GlobalSimulatorScreen.jsm'); michael@0: michael@0: let DEBUG_PREFIX = 'SimulatorScreen.js - '; michael@0: function debug() { michael@0: //dump(DEBUG_PREFIX + Array.slice(arguments) + '\n'); michael@0: } michael@0: michael@0: function fireOrientationEvent(window) { michael@0: let e = new window.Event('mozorientationchange'); michael@0: window.screen.dispatchEvent(e); michael@0: } michael@0: michael@0: function hookScreen(window) { michael@0: let nodePrincipal = window.document.nodePrincipal; michael@0: let origin = nodePrincipal.origin; michael@0: if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) { michael@0: Cu.reportError('deny mozLockOrientation:' + origin + 'is not installed'); michael@0: return; michael@0: } michael@0: michael@0: let screen = window.wrappedJSObject.screen; michael@0: michael@0: screen.mozLockOrientation = function (orientation) { michael@0: debug('mozLockOrientation:', orientation, 'from', origin); michael@0: michael@0: // Normalize and do some checks against orientation input michael@0: if (typeof(orientation) == 'string') { michael@0: orientation = [orientation]; michael@0: } michael@0: michael@0: function isInvalidOrientationString(str) { michael@0: return typeof(str) != 'string' || michael@0: !str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/); michael@0: } michael@0: if (!Array.isArray(orientation) || michael@0: orientation.some(isInvalidOrientationString)) { michael@0: Cu.reportError('Invalid orientation "' + orientation + '"'); michael@0: return false; michael@0: } michael@0: michael@0: GlobalSimulatorScreen.lock(orientation); michael@0: michael@0: return true; michael@0: }; michael@0: michael@0: screen.mozUnlockOrientation = function() { michael@0: debug('mozOrientationUnlock from', origin); michael@0: GlobalSimulatorScreen.unlock(); michael@0: return true; michael@0: }; michael@0: michael@0: Object.defineProperty(screen, 'width', { michael@0: get: function () GlobalSimulatorScreen.width michael@0: }); michael@0: Object.defineProperty(screen, 'height', { michael@0: get: function () GlobalSimulatorScreen.height michael@0: }); michael@0: Object.defineProperty(screen, 'mozOrientation', { michael@0: get: function () GlobalSimulatorScreen.mozOrientation michael@0: }); michael@0: } michael@0: michael@0: function SimulatorScreen() {} michael@0: SimulatorScreen.prototype = { michael@0: classID: Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'), michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, michael@0: Ci.nsISupportsWeakReference]), michael@0: _windows: new Map(), michael@0: michael@0: observe: function (subject, topic, data) { michael@0: let windows = this._windows; michael@0: switch (topic) { michael@0: case 'profile-after-change': michael@0: Services.obs.addObserver(this, 'document-element-inserted', false); michael@0: Services.obs.addObserver(this, 'simulator-orientation-change', false); michael@0: Services.obs.addObserver(this, 'inner-window-destroyed', false); michael@0: break; michael@0: michael@0: case 'document-element-inserted': michael@0: let window = subject.defaultView; michael@0: if (!window) { michael@0: return; michael@0: } michael@0: michael@0: hookScreen(window); michael@0: michael@0: var id = window.QueryInterface(Ci.nsIInterfaceRequestor) michael@0: .getInterface(Ci.nsIDOMWindowUtils) michael@0: .currentInnerWindowID; michael@0: windows.set(id, window); michael@0: break; michael@0: michael@0: case 'inner-window-destroyed': michael@0: var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; michael@0: windows.delete(id); michael@0: break; michael@0: michael@0: case 'simulator-orientation-change': michael@0: windows.forEach(fireOrientationEvent); michael@0: break; michael@0: } michael@0: } michael@0: }; michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]);