Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | "use strict"; |
michael@0 | 4 | |
michael@0 | 5 | let {devtools} = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {}); |
michael@0 | 6 | let TiltManager = devtools.require("devtools/tilt/tilt").TiltManager; |
michael@0 | 7 | let TiltGL = devtools.require("devtools/tilt/tilt-gl"); |
michael@0 | 8 | let {EPSILON, TiltMath, vec3, mat3, mat4, quat4} = devtools.require("devtools/tilt/tilt-math"); |
michael@0 | 9 | let TiltUtils = devtools.require("devtools/tilt/tilt-utils"); |
michael@0 | 10 | let {TiltVisualizer} = devtools.require("devtools/tilt/tilt-visualizer"); |
michael@0 | 11 | |
michael@0 | 12 | let tempScope = {}; |
michael@0 | 13 | Components.utils.import("resource://gre/modules/devtools/LayoutHelpers.jsm", tempScope); |
michael@0 | 14 | let LayoutHelpers = tempScope.LayoutHelpers; |
michael@0 | 15 | |
michael@0 | 16 | |
michael@0 | 17 | const DEFAULT_HTML = "data:text/html," + |
michael@0 | 18 | "<DOCTYPE html>" + |
michael@0 | 19 | "<html>" + |
michael@0 | 20 | "<head>" + |
michael@0 | 21 | "<meta charset='utf-8'/>" + |
michael@0 | 22 | "<title>Three Laws</title>" + |
michael@0 | 23 | "</head>" + |
michael@0 | 24 | "<body>" + |
michael@0 | 25 | "<div id='first-law'>" + |
michael@0 | 26 | "A robot may not injure a human being or, through inaction, allow a " + |
michael@0 | 27 | "human being to come to harm." + |
michael@0 | 28 | "</div>" + |
michael@0 | 29 | "<div>" + |
michael@0 | 30 | "A robot must obey the orders given to it by human beings, except " + |
michael@0 | 31 | "where such orders would conflict with the First Law." + |
michael@0 | 32 | "</div>" + |
michael@0 | 33 | "<div>" + |
michael@0 | 34 | "A robot must protect its own existence as long as such protection " + |
michael@0 | 35 | "does not conflict with the First or Second Laws." + |
michael@0 | 36 | "</div>" + |
michael@0 | 37 | "<div id='far-far-away' style='position: absolute; top: 250%;'>" + |
michael@0 | 38 | "I like bacon." + |
michael@0 | 39 | "</div>" + |
michael@0 | 40 | "<body>" + |
michael@0 | 41 | "</html>"; |
michael@0 | 42 | |
michael@0 | 43 | let Tilt = TiltManager.getTiltForBrowser(window); |
michael@0 | 44 | |
michael@0 | 45 | const STARTUP = Tilt.NOTIFICATIONS.STARTUP; |
michael@0 | 46 | const INITIALIZING = Tilt.NOTIFICATIONS.INITIALIZING; |
michael@0 | 47 | const INITIALIZED = Tilt.NOTIFICATIONS.INITIALIZED; |
michael@0 | 48 | const DESTROYING = Tilt.NOTIFICATIONS.DESTROYING; |
michael@0 | 49 | const BEFORE_DESTROYED = Tilt.NOTIFICATIONS.BEFORE_DESTROYED; |
michael@0 | 50 | const DESTROYED = Tilt.NOTIFICATIONS.DESTROYED; |
michael@0 | 51 | const SHOWN = Tilt.NOTIFICATIONS.SHOWN; |
michael@0 | 52 | const HIDDEN = Tilt.NOTIFICATIONS.HIDDEN; |
michael@0 | 53 | const HIGHLIGHTING = Tilt.NOTIFICATIONS.HIGHLIGHTING; |
michael@0 | 54 | const UNHIGHLIGHTING = Tilt.NOTIFICATIONS.UNHIGHLIGHTING; |
michael@0 | 55 | const NODE_REMOVED = Tilt.NOTIFICATIONS.NODE_REMOVED; |
michael@0 | 56 | |
michael@0 | 57 | const TILT_ENABLED = Services.prefs.getBoolPref("devtools.tilt.enabled"); |
michael@0 | 58 | |
michael@0 | 59 | gDevTools.testing = true; |
michael@0 | 60 | SimpleTest.registerCleanupFunction(() => { |
michael@0 | 61 | gDevTools.testing = false; |
michael@0 | 62 | }); |
michael@0 | 63 | |
michael@0 | 64 | function isTiltEnabled() { |
michael@0 | 65 | info("Apparently, Tilt is" + (TILT_ENABLED ? "" : " not") + " enabled."); |
michael@0 | 66 | return TILT_ENABLED; |
michael@0 | 67 | } |
michael@0 | 68 | |
michael@0 | 69 | function isWebGLSupported() { |
michael@0 | 70 | let supported = !TiltGL.isWebGLForceEnabled() && |
michael@0 | 71 | TiltGL.isWebGLSupported() && |
michael@0 | 72 | TiltGL.create3DContext(createCanvas()); |
michael@0 | 73 | |
michael@0 | 74 | info("Apparently, WebGL is" + (supported ? "" : " not") + " supported."); |
michael@0 | 75 | return supported; |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | function isApprox(num1, num2, delta) { |
michael@0 | 79 | if (Math.abs(num1 - num2) > (delta || EPSILON)) { |
michael@0 | 80 | info("isApprox expected " + num1 + ", got " + num2 + " instead."); |
michael@0 | 81 | return false; |
michael@0 | 82 | } |
michael@0 | 83 | return true; |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | function isApproxVec(vec1, vec2, delta) { |
michael@0 | 87 | vec1 = Array.prototype.slice.call(vec1); |
michael@0 | 88 | vec2 = Array.prototype.slice.call(vec2); |
michael@0 | 89 | |
michael@0 | 90 | if (vec1.length !== vec2.length) { |
michael@0 | 91 | return false; |
michael@0 | 92 | } |
michael@0 | 93 | for (let i = 0, len = vec1.length; i < len; i++) { |
michael@0 | 94 | if (!isApprox(vec1[i], vec2[i], delta)) { |
michael@0 | 95 | info("isApproxVec expected [" + vec1 + "], got [" + vec2 + "] instead."); |
michael@0 | 96 | return false; |
michael@0 | 97 | } |
michael@0 | 98 | } |
michael@0 | 99 | return true; |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | function isEqualVec(vec1, vec2) { |
michael@0 | 103 | vec1 = Array.prototype.slice.call(vec1); |
michael@0 | 104 | vec2 = Array.prototype.slice.call(vec2); |
michael@0 | 105 | |
michael@0 | 106 | if (vec1.length !== vec2.length) { |
michael@0 | 107 | return false; |
michael@0 | 108 | } |
michael@0 | 109 | for (let i = 0, len = vec1.length; i < len; i++) { |
michael@0 | 110 | if (vec1[i] !== vec2[i]) { |
michael@0 | 111 | info("isEqualVec expected [" + vec1 + "], got [" + vec2 + "] instead."); |
michael@0 | 112 | return false; |
michael@0 | 113 | } |
michael@0 | 114 | } |
michael@0 | 115 | return true; |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | function createCanvas() { |
michael@0 | 119 | return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | |
michael@0 | 123 | function createTab(callback, location) { |
michael@0 | 124 | info("Creating a tab, with callback " + typeof callback + |
michael@0 | 125 | ", and location " + location + "."); |
michael@0 | 126 | |
michael@0 | 127 | let tab = gBrowser.selectedTab = gBrowser.addTab(); |
michael@0 | 128 | |
michael@0 | 129 | gBrowser.selectedBrowser.addEventListener("load", function onLoad() { |
michael@0 | 130 | gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); |
michael@0 | 131 | callback(tab); |
michael@0 | 132 | }, true); |
michael@0 | 133 | |
michael@0 | 134 | gBrowser.selectedBrowser.contentWindow.location = location || DEFAULT_HTML; |
michael@0 | 135 | return tab; |
michael@0 | 136 | } |
michael@0 | 137 | |
michael@0 | 138 | |
michael@0 | 139 | function createTilt(callbacks, close, suddenDeath) { |
michael@0 | 140 | info("Creating Tilt, with callbacks {" + Object.keys(callbacks) + "}" + |
michael@0 | 141 | ", autoclose param " + close + |
michael@0 | 142 | ", and sudden death handler " + typeof suddenDeath + "."); |
michael@0 | 143 | |
michael@0 | 144 | handleFailure(suddenDeath); |
michael@0 | 145 | |
michael@0 | 146 | Services.prefs.setBoolPref("webgl.verbose", true); |
michael@0 | 147 | TiltUtils.Output.suppressAlerts = true; |
michael@0 | 148 | |
michael@0 | 149 | info("Attempting to start Tilt."); |
michael@0 | 150 | Services.obs.addObserver(onTiltOpen, INITIALIZING, false); |
michael@0 | 151 | Tilt.toggle(); |
michael@0 | 152 | |
michael@0 | 153 | function onTiltOpen() { |
michael@0 | 154 | info("Tilt was opened."); |
michael@0 | 155 | Services.obs.removeObserver(onTiltOpen, INITIALIZING); |
michael@0 | 156 | |
michael@0 | 157 | executeSoon(function() { |
michael@0 | 158 | if ("function" === typeof callbacks.onTiltOpen) { |
michael@0 | 159 | info("Calling 'onTiltOpen'."); |
michael@0 | 160 | callbacks.onTiltOpen(Tilt.visualizers[Tilt.currentWindowId]); |
michael@0 | 161 | } |
michael@0 | 162 | if (close) { |
michael@0 | 163 | executeSoon(function() { |
michael@0 | 164 | info("Attempting to close Tilt."); |
michael@0 | 165 | Services.obs.addObserver(onTiltClose, DESTROYED, false); |
michael@0 | 166 | Tilt.destroy(Tilt.currentWindowId); |
michael@0 | 167 | }); |
michael@0 | 168 | } |
michael@0 | 169 | }); |
michael@0 | 170 | } |
michael@0 | 171 | |
michael@0 | 172 | function onTiltClose() { |
michael@0 | 173 | info("Tilt was closed."); |
michael@0 | 174 | Services.obs.removeObserver(onTiltClose, DESTROYED); |
michael@0 | 175 | |
michael@0 | 176 | executeSoon(function() { |
michael@0 | 177 | if ("function" === typeof callbacks.onTiltClose) { |
michael@0 | 178 | info("Calling 'onTiltClose'."); |
michael@0 | 179 | callbacks.onTiltClose(); |
michael@0 | 180 | } |
michael@0 | 181 | if ("function" === typeof callbacks.onEnd) { |
michael@0 | 182 | info("Calling 'onEnd'."); |
michael@0 | 183 | callbacks.onEnd(); |
michael@0 | 184 | } |
michael@0 | 185 | }); |
michael@0 | 186 | } |
michael@0 | 187 | |
michael@0 | 188 | function handleFailure(suddenDeath) { |
michael@0 | 189 | Tilt.failureCallback = function() { |
michael@0 | 190 | info("Tilt FAIL."); |
michael@0 | 191 | Services.obs.removeObserver(onTiltOpen, INITIALIZING); |
michael@0 | 192 | |
michael@0 | 193 | info("Now relying on sudden death handler " + typeof suddenDeath + "."); |
michael@0 | 194 | suddenDeath && suddenDeath(); |
michael@0 | 195 | } |
michael@0 | 196 | } |
michael@0 | 197 | } |
michael@0 | 198 | |
michael@0 | 199 | function getPickablePoint(presenter) { |
michael@0 | 200 | let vertices = presenter._meshStacks[0].vertices.components; |
michael@0 | 201 | |
michael@0 | 202 | let topLeft = vec3.create([vertices[0], vertices[1], vertices[2]]); |
michael@0 | 203 | let bottomRight = vec3.create([vertices[6], vertices[7], vertices[8]]); |
michael@0 | 204 | let center = vec3.lerp(topLeft, bottomRight, 0.5, []); |
michael@0 | 205 | |
michael@0 | 206 | let renderer = presenter._renderer; |
michael@0 | 207 | let viewport = [0, 0, renderer.width, renderer.height]; |
michael@0 | 208 | |
michael@0 | 209 | return vec3.project(center, viewport, renderer.mvMatrix, renderer.projMatrix); |
michael@0 | 210 | } |