├── .gitignore ├── .jpmignore ├── .npmignore ├── LICENSE ├── README.md ├── data └── content-script.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.xpi 3 | *.zip 4 | *~ 5 | .DS_Store 6 | @* 7 | node_modules 8 | -------------------------------------------------------------------------------- /.jpmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.xpi 3 | *.zip 4 | *~ 5 | .DS_Store 6 | .git 7 | .gitignore 8 | .jpmignore 9 | .npmignore 10 | @* 11 | README.md 12 | node_modules 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.xpi 3 | *.zip 4 | *~ 5 | .DS_Store 6 | .git 7 | .gitignore 8 | .jpmignore 9 | .npmignore 10 | @* 11 | node_modules 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright © 2016 MozVR. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mozilla WebVR Plus 2 | 3 | Firefox extension that manages browser setting flags for optimal WebVR support, avoiding the need to make `about:config` changes. 4 | 5 | The latest public version of this extension lives on __[addons.mozilla.org](https://addons.mozilla.org/en-US/firefox/addon/mozilla-webvr-enabler/)__. 6 | 7 | 8 | ## Development 9 | 10 | We use [`jpm`](https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/jpm), which requires `npm` (`brew install npm`, if you're on OS X). 11 | 12 | Then to install the Node dependencies: 13 | 14 | ```bash 15 | npm install 16 | ``` 17 | 18 | ### Building 19 | 20 | ```bash 21 | npm run xpi 22 | ``` 23 | 24 | ### Running 25 | 26 | ```bash 27 | npm run run 28 | ``` 29 | 30 | #### Testing the `.xpi` without `jpm` 31 | 32 | 1. If you'd like to test a generated `.xpi` with a different version/build of Firefox, you must first disable the check that allows only signed add-ons to be installed. In Firefox, open `about:config` and change `xpinstall.signatures.required` to `false`. 33 | 2. Drag the generated `.xpi` from your file system onto any active browser window in Firefox. 34 | 3. Click the "Install" button! 35 | 36 | ### Publishing 37 | 38 | To update this [extension](https://addons.mozilla.org/en-US/firefox/addon/mozilla-webvr-enabler/), first run this command: 39 | 40 | ```bash 41 | npm run xpi 42 | ``` 43 | 44 | And then [upload the new version to AMO](https://addons.mozilla.org/developers/addon/mozilla-webvr-enabler/versions). 45 | -------------------------------------------------------------------------------- /data/content-script.js: -------------------------------------------------------------------------------- 1 | /* global createObjectIn, self, unsafeWindow */ 2 | 3 | var WEBVRPLUS = createObjectIn(unsafeWindow, {defineAs: 'WEBVRPLUS'}); 4 | 5 | function parseMsg (msg) { 6 | if (!msg) { return; } 7 | 8 | try { 9 | msg = JSON.parse(msg); 10 | } catch (e) { 11 | return; 12 | } 13 | 14 | return msg; 15 | } 16 | 17 | function stringifyMsg (type, data) { 18 | return JSON.stringify({ 19 | type: type, 20 | data: data 21 | }); 22 | } 23 | 24 | self.port.on('msg', function (msg) { 25 | msg = parseMsg(msg); 26 | if (!msg) { return; } 27 | 28 | var type = msg.type; 29 | var data = msg.data; 30 | 31 | switch (type) { 32 | case 'version': 33 | WEBVRPLUS.version = data; 34 | break; 35 | } 36 | }); 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* global require, exports */ 2 | 3 | const { Cc, Ci, Cu, Cm } = require('chrome'); 4 | const { PageMod } = require('sdk/page-mod'); 5 | const self = require('sdk/self'); 6 | const prefs = require('sdk/preferences/service'); 7 | 8 | Cu.import('resource://gre/modules/Services.jsm'); 9 | 10 | const pkg = require('./package.json'); 11 | 12 | const PREFS = { 13 | // Enables WebVR. Not needed for Nightly, but we need to keep for other versions. 14 | 'dom.vr.enabled': true, 15 | 16 | // Enables the OpenVR API (e.g., Steam VR). 17 | 'dom.vr.openvr.enabled': true, 18 | 19 | // Enables mirroring. It's confusing otherwise, if you're not looking at your headset. 20 | 'gfx.vr.mirror-textures': true 21 | }; 22 | 23 | function setDefaultPrefs () { 24 | var needsReset = false; 25 | 26 | Object.keys(PREFS).forEach(function (key) { 27 | if (prefs.get(key) === PREFS[key]) { return; } 28 | prefs.set(key, PREFS[key]); 29 | needsReset = true; 30 | }); 31 | 32 | if (!needsReset) { return; } 33 | 34 | var title = 'Restart Required'; 35 | var msg = 'Installing the WebVR Plus add-on for the first time requires a restart. Restart now?'; 36 | let shouldProceed = Services.prompt.confirm(null, title, msg); 37 | if (!shouldProceed) { return; } 38 | 39 | let cancelQuit = Cc['@mozilla.org/supports-PRBool;1'].createInstance(Ci.nsISupportsPRBool); 40 | Services.obs.notifyObservers(cancelQuit, 'quit-application-requested', 'restart'); 41 | shouldProceed = !cancelQuit.data; 42 | if (!shouldProceed) { return; } 43 | 44 | Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); 45 | } 46 | 47 | function revertPrefs () { 48 | Object.keys(PREFS).forEach(function (key) { 49 | prefs.reset(key); 50 | }); 51 | } 52 | 53 | function stringifyMsg (type, data) { 54 | return JSON.stringify({ 55 | type: type, 56 | data: data 57 | }); 58 | } 59 | 60 | function sendMsg (worker, type, data) { 61 | worker.port.emit('msg', stringifyMsg(type, data)); 62 | } 63 | 64 | function startListening (worker) { 65 | sendMsg(worker, 'version', pkg.version); 66 | } 67 | 68 | PageMod({ 69 | include: '*', 70 | contentScriptFile: self.data.url('content-script.js'), 71 | contentScriptWhen: 'ready', 72 | onAttach: startListening 73 | }); 74 | 75 | // Covers startup, install, upgrade, downgrade, enable. 76 | exports.main = function (opts) { 77 | if (opts.loadReason === 'startup') { return; } 78 | setDefaultPrefs(); 79 | }; 80 | 81 | // Covers uninstall, disable, shutdown, downgrade, upgrade. 82 | exports.onUnload = function (reason) { 83 | if (reason === 'shutdown') { return; } 84 | revertPrefs(); 85 | }; 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Mozilla WebVR Plus", 3 | "name": "mozillawebvrenabler", 4 | "version": "0.6.0", 5 | "description": "Firefox extension that manages browser prefs for optimal WebVR support, avoiding the need to make about:config changes.", 6 | "main": "index.js", 7 | "author": "Mozilla", 8 | "engines": { 9 | "firefox": ">=38.0a1", 10 | "fennec": ">=38.0a1" 11 | }, 12 | "license": "MIT", 13 | "devDependencies": { 14 | "jpm": "^1.0.4" 15 | }, 16 | "scripts": { 17 | "start": "npm run build && npm run run", 18 | "build": "jpm build", 19 | "run": "jpm run", 20 | "xpi": "jpm xpi" 21 | } 22 | } 23 | --------------------------------------------------------------------------------