From 7dad2424a4c84f1b1ec9843d3cf4c4166adb2306 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Thu, 3 Mar 2016 15:41:26 +1100 Subject: [PATCH 01/55] Bug 1253120 - drop the restriction on param values passed to showFirefoxAccounts. r=MattN --- browser/components/uitour/UITour.jsm | 6 +++--- .../uitour/test/browser_UITour_sync.js | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/browser/components/uitour/UITour.jsm b/browser/components/uitour/UITour.jsm index 016395c471b3..c35646aff2a7 100644 --- a/browser/components/uitour/UITour.jsm +++ b/browser/components/uitour/UITour.jsm @@ -840,15 +840,15 @@ this.UITour = { return false; } if (campaignParams) { - // The regex that both the name and value of each param must match. + // The regex that the name of each param must match - there's no + // character restriction on the value - they will be escaped as necessary. let reSimpleString = /^[-_a-zA-Z0-9]*$/; for (let name in campaignParams) { let value = campaignParams[name]; if (typeof name != "string" || typeof value != "string" || !name.startsWith("utm_") || value.length == 0 || - !reSimpleString.test(name) || - !reSimpleString.test(value)) { + !reSimpleString.test(name)) { log.warn("_populateCampaignParams: invalid campaign param specified"); return false; } diff --git a/browser/components/uitour/test/browser_UITour_sync.js b/browser/components/uitour/test/browser_UITour_sync.js index c533d06f5f17..03673df9b5b4 100644 --- a/browser/components/uitour/test/browser_UITour_sync.js +++ b/browser/components/uitour/test/browser_UITour_sync.js @@ -34,6 +34,18 @@ add_UITour_task(function* test_firefoxAccountsValidParams() { "about:accounts?action=signup&entrypoint=uitour&utm_foo=foo&utm_bar=bar"); }); +add_UITour_task(function* test_firefoxAccountsNonAlphaValue() { + // All characters in the value are allowed, but they must be automatically escaped. + // (we throw a unicode character in there too - it's not auto-utf8 encoded, + // but that's ok, so long as it is escaped correctly.) + let value = "foo& /=?:\\\xa9"; + // encodeURIComponent encodes spaces to %20 but we want "+" + let expected = encodeURIComponent(value).replace(/%20/g, "+"); + yield gContentAPI.showFirefoxAccounts({ utm_foo: value }); + yield BrowserTestUtils.browserLoaded(gTestTab.linkedBrowser, false, + "about:accounts?action=signup&entrypoint=uitour&utm_foo=" + expected); +}); + // A helper to check the request was ignored due to invalid params. function* checkAboutAccountsNotLoaded() { try { @@ -63,9 +75,3 @@ add_UITour_task(function* test_firefoxAccountsNonAlphaName() { yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo", "utm_bar=": "bar" }); yield checkAboutAccountsNotLoaded(); }); - -add_UITour_task(function* test_firefoxAccountsNonAlphaValue() { - // Any non-alpha value should be rejected. - yield gContentAPI.showFirefoxAccounts({ utm_foo: "foo&" }); - yield checkAboutAccountsNotLoaded(); -}); From de4f7ccdea1f7ebc553f9c0726031e6840faa57e Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Thu, 3 Mar 2016 02:27:22 -0800 Subject: [PATCH 02/55] Bug 1245875 - Factor out webgl helpers out of tilt. r=vporof --- devtools/client/canvasdebugger/test/head.js | 7 +-- devtools/client/shadereditor/test/head.js | 16 ++---- devtools/client/shared/moz.build | 1 + devtools/client/shared/webgl-utils.js | 54 +++++++++++++++++++++ 4 files changed, 60 insertions(+), 18 deletions(-) create mode 100644 devtools/client/shared/webgl-utils.js diff --git a/devtools/client/canvasdebugger/test/head.js b/devtools/client/canvasdebugger/test/head.js index 1d8ba11268b7..378b6cf9c992 100644 --- a/devtools/client/canvasdebugger/test/head.js +++ b/devtools/client/canvasdebugger/test/head.js @@ -17,9 +17,9 @@ var { CallWatcherFront } = require("devtools/server/actors/call-watcher"); var { CanvasFront } = require("devtools/server/actors/canvas"); var { setTimeout } = require("sdk/timers"); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); -var TiltGL = require("devtools/client/tilt/tilt-gl"); var { TargetFactory } = require("devtools/client/framework/target"); var { Toolbox } = require("devtools/client/framework/toolbox"); +var { isWebGLSupported } = require("devtools/client/shared/webgl-utils"); var mm = null const FRAME_SCRIPT_UTILS_URL = "chrome://devtools/content/shared/frame-script-utils.js"; @@ -140,10 +140,7 @@ function isTestingSupported() { return true; } - let supported = - !TiltGL.isWebGLForceEnabled() && - TiltGL.isWebGLSupported() && - TiltGL.create3DContext(createCanvas()); + let supported = isWebGLSupported(); info("This test requires WebGL support."); info("Apparently, WebGL is" + (supported ? "" : " not") + " supported."); diff --git a/devtools/client/shadereditor/test/head.js b/devtools/client/shadereditor/test/head.js index 67129eadd62d..174dc5fdf91e 100644 --- a/devtools/client/shadereditor/test/head.js +++ b/devtools/client/shadereditor/test/head.js @@ -14,9 +14,9 @@ var { DebuggerClient } = require("devtools/shared/client/main"); var { DebuggerServer } = require("devtools/server/main"); var { WebGLFront } = require("devtools/server/actors/webgl"); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); -var TiltGL = require("devtools/client/tilt/tilt-gl"); -var {TargetFactory} = require("devtools/client/framework/target"); -var {Toolbox} = require("devtools/client/framework/toolbox"); +var { TargetFactory } = require("devtools/client/framework/target"); +var { Toolbox } = require("devtools/client/framework/toolbox"); +var { isWebGLSupported } = require("devtools/client/shared/webgl-utils"); var mm = null; const FRAME_SCRIPT_UTILS_URL = "chrome://devtools/content/shared/frame-script-utils.js" @@ -126,16 +126,6 @@ function createCanvas() { return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); } -function isWebGLSupported() { - let supported = - !TiltGL.isWebGLForceEnabled() && - TiltGL.isWebGLSupported() && - TiltGL.create3DContext(createCanvas()); - - info("Apparently, WebGL is" + (supported ? "" : " not") + " supported."); - return supported; -} - function once(aTarget, aEventName, aUseCapture = false) { info("Waiting for event: '" + aEventName + "' on " + aTarget + "."); diff --git a/devtools/client/shared/moz.build b/devtools/client/shared/moz.build index d6cd3f87bc50..c3ab5dae89d5 100644 --- a/devtools/client/shared/moz.build +++ b/devtools/client/shared/moz.build @@ -43,4 +43,5 @@ DevToolsModules( 'theme.js', 'undo.js', 'view-source.js', + 'webgl-utils.js', ) diff --git a/devtools/client/shared/webgl-utils.js b/devtools/client/shared/webgl-utils.js new file mode 100644 index 000000000000..8865dc9ddfe4 --- /dev/null +++ b/devtools/client/shared/webgl-utils.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const { Cc, Ci } = require("chrome"); +const Services = require("Services"); + +const WEBGL_CONTEXT_NAME = "experimental-webgl"; + +function isWebGLForceEnabled() +{ + return Services.prefs.getBoolPref("webgl.force-enabled"); +} + +function isWebGLSupportedByGFX() +{ + let supported = false; + + try { + let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); + let angle = gfxInfo.FEATURE_WEBGL_ANGLE; + let opengl = gfxInfo.FEATURE_WEBGL_OPENGL; + + // if either the Angle or OpenGL renderers are available, WebGL should work + supported = gfxInfo.getFeatureStatus(angle) === gfxInfo.FEATURE_STATUS_OK || + gfxInfo.getFeatureStatus(opengl) === gfxInfo.FEATURE_STATUS_OK; + } catch(e) { + return false; + } + return supported; +} + +function create3DContext(aCanvas) +{ + // try to get a valid context from an existing canvas + let context = null; + try { + context = aCanvas.getContext(WEBGL_CONTEXT_NAME, aFlags); + } catch(e) { + return null; + } + return context; +} + +function isWebGLSupported() { + let supported = + !isWebGLForceEnabled() && + isWebGLSupportedByGFX() && + create3DContext(createCanvas()); + + return supported; +} +exports.isWebGLSupported = isWebGLSupported; From ffdbd09825425012bdca0be85ebecdc4e98c755a Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Thu, 3 Mar 2016 02:27:22 -0800 Subject: [PATCH 03/55] Bug 1245875 - Remove Tilt from tree. r=vporof,jwalker --- .eslintignore | 1 - .../commandline/test/browser_cmd_pref1.js | 40 +- ...browser_toolbox_options_disable_buttons.js | 6 - devtools/client/framework/toolbox-options.js | 3 - devtools/client/framework/toolbox.js | 24 - devtools/client/jar.mn | 2 - devtools/client/locales/en-US/tilt.properties | 49 - devtools/client/moz.build | 1 - devtools/client/preferences/devtools.js | 8 +- devtools/client/shared/telemetry.js | 5 - devtools/client/shared/test/browser.ini | 3 - .../test/browser_telemetry_button_tilt.js | 110 - .../client/themes/images/command-tilt.png | Bin 311 -> 0 bytes .../client/themes/images/command-tilt@2x.png | Bin 449 -> 0 bytes devtools/client/themes/toolbars.css | 8 - devtools/client/tilt/TiltWorkerCrafter.js | 281 -- devtools/client/tilt/TiltWorkerPicker.js | 186 -- devtools/client/tilt/moz.build | 17 - devtools/client/tilt/test/.eslintrc | 4 - devtools/client/tilt/test/browser.ini | 54 - .../tilt/test/browser_tilt_01_lazy_getter.js | 14 - .../test/browser_tilt_02_notifications-seq.js | 99 - .../browser_tilt_02_notifications-tabs.js | 179 -- .../test/browser_tilt_02_notifications.js | 131 - .../tilt/test/browser_tilt_03_tab_switch.js | 110 - .../test/browser_tilt_04_initialization.js | 59 - .../test/browser_tilt_05_destruction-esc.js | 51 - .../test/browser_tilt_05_destruction-url.js | 51 - .../tilt/test/browser_tilt_05_destruction.js | 51 - .../browser_tilt_arcball-reset-typeahead.js | 132 - .../tilt/test/browser_tilt_arcball-reset.js | 130 - .../client/tilt/test/browser_tilt_arcball.js | 496 ---- .../tilt/test/browser_tilt_controller.js | 138 - .../client/tilt/test/browser_tilt_gl01.js | 157 -- .../client/tilt/test/browser_tilt_gl02.js | 46 - .../client/tilt/test/browser_tilt_gl03.js | 69 - .../client/tilt/test/browser_tilt_gl04.js | 126 - .../client/tilt/test/browser_tilt_gl05.js | 42 - .../client/tilt/test/browser_tilt_gl06.js | 59 - .../client/tilt/test/browser_tilt_gl07.js | 60 - .../client/tilt/test/browser_tilt_gl08.js | 51 - .../client/tilt/test/browser_tilt_math01.js | 59 - .../client/tilt/test/browser_tilt_math02.js | 104 - .../client/tilt/test/browser_tilt_math03.js | 33 - .../client/tilt/test/browser_tilt_math04.js | 49 - .../client/tilt/test/browser_tilt_math05.js | 101 - .../client/tilt/test/browser_tilt_math06.js | 42 - .../client/tilt/test/browser_tilt_math07.js | 49 - .../client/tilt/test/browser_tilt_picking.js | 56 - .../tilt/test/browser_tilt_picking_delete.js | 78 - .../browser_tilt_picking_highlight01-offs.js | 77 - .../test/browser_tilt_picking_highlight01.js | 77 - .../test/browser_tilt_picking_highlight02.js | 72 - .../test/browser_tilt_picking_highlight03.js | 72 - .../test/browser_tilt_picking_inspector.js | 76 - .../tilt/test/browser_tilt_picking_miv.js | 78 - .../client/tilt/test/browser_tilt_utils01.js | 69 - .../client/tilt/test/browser_tilt_utils02.js | 21 - .../client/tilt/test/browser_tilt_utils03.js | 18 - .../client/tilt/test/browser_tilt_utils04.js | 54 - .../client/tilt/test/browser_tilt_utils05.js | 101 - .../client/tilt/test/browser_tilt_utils06.js | 44 - .../client/tilt/test/browser_tilt_utils07.js | 159 -- .../client/tilt/test/browser_tilt_utils08.js | 85 - .../tilt/test/browser_tilt_visualizer.js | 128 - .../client/tilt/test/browser_tilt_zoom.js | 117 - devtools/client/tilt/test/head.js | 214 -- devtools/client/tilt/tilt-commands.js | 228 -- devtools/client/tilt/tilt-gl.js | 1594 ----------- devtools/client/tilt/tilt-math.js | 2322 ----------------- devtools/client/tilt/tilt-utils.js | 614 ----- devtools/client/tilt/tilt-visualizer-style.js | 46 - devtools/client/tilt/tilt-visualizer.js | 2255 ---------------- devtools/client/tilt/tilt.js | 264 -- .../locales/en-US/gclicommands.properties | 134 - 75 files changed, 21 insertions(+), 12522 deletions(-) delete mode 100755 devtools/client/locales/en-US/tilt.properties delete mode 100644 devtools/client/shared/test/browser_telemetry_button_tilt.js delete mode 100644 devtools/client/themes/images/command-tilt.png delete mode 100644 devtools/client/themes/images/command-tilt@2x.png delete mode 100644 devtools/client/tilt/TiltWorkerCrafter.js delete mode 100644 devtools/client/tilt/TiltWorkerPicker.js delete mode 100644 devtools/client/tilt/moz.build delete mode 100644 devtools/client/tilt/test/.eslintrc delete mode 100644 devtools/client/tilt/test/browser.ini delete mode 100644 devtools/client/tilt/test/browser_tilt_01_lazy_getter.js delete mode 100644 devtools/client/tilt/test/browser_tilt_02_notifications-seq.js delete mode 100644 devtools/client/tilt/test/browser_tilt_02_notifications-tabs.js delete mode 100644 devtools/client/tilt/test/browser_tilt_02_notifications.js delete mode 100644 devtools/client/tilt/test/browser_tilt_03_tab_switch.js delete mode 100644 devtools/client/tilt/test/browser_tilt_04_initialization.js delete mode 100644 devtools/client/tilt/test/browser_tilt_05_destruction-esc.js delete mode 100644 devtools/client/tilt/test/browser_tilt_05_destruction-url.js delete mode 100644 devtools/client/tilt/test/browser_tilt_05_destruction.js delete mode 100644 devtools/client/tilt/test/browser_tilt_arcball-reset-typeahead.js delete mode 100644 devtools/client/tilt/test/browser_tilt_arcball-reset.js delete mode 100644 devtools/client/tilt/test/browser_tilt_arcball.js delete mode 100644 devtools/client/tilt/test/browser_tilt_controller.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl01.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl02.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl03.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl04.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl05.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl06.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl07.js delete mode 100644 devtools/client/tilt/test/browser_tilt_gl08.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math01.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math02.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math03.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math04.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math05.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math06.js delete mode 100644 devtools/client/tilt/test/browser_tilt_math07.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_delete.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_highlight01-offs.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_highlight01.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_highlight02.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_highlight03.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_inspector.js delete mode 100644 devtools/client/tilt/test/browser_tilt_picking_miv.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils01.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils02.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils03.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils04.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils05.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils06.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils07.js delete mode 100644 devtools/client/tilt/test/browser_tilt_utils08.js delete mode 100644 devtools/client/tilt/test/browser_tilt_visualizer.js delete mode 100644 devtools/client/tilt/test/browser_tilt_zoom.js delete mode 100644 devtools/client/tilt/test/head.js delete mode 100644 devtools/client/tilt/tilt-commands.js delete mode 100644 devtools/client/tilt/tilt-gl.js delete mode 100644 devtools/client/tilt/tilt-math.js delete mode 100644 devtools/client/tilt/tilt-utils.js delete mode 100644 devtools/client/tilt/tilt-visualizer-style.js delete mode 100644 devtools/client/tilt/tilt-visualizer.js delete mode 100644 devtools/client/tilt/tilt.js diff --git a/.eslintignore b/.eslintignore index c495acf0805e..112bda31eb15 100644 --- a/.eslintignore +++ b/.eslintignore @@ -103,7 +103,6 @@ devtools/client/scratchpad/** devtools/client/shadereditor/** devtools/client/shared/** devtools/client/sourceeditor/** -devtools/client/tilt/** devtools/client/webaudioeditor/** devtools/client/webconsole/** devtools/client/webide/** diff --git a/devtools/client/commandline/test/browser_cmd_pref1.js b/devtools/client/commandline/test/browser_cmd_pref1.js index 040b23ca2473..2fb6abfa534e 100644 --- a/devtools/client/commandline/test/browser_cmd_pref1.js +++ b/devtools/client/commandline/test/browser_cmd_pref1.js @@ -17,8 +17,8 @@ function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); - let tiltEnabledOrig = prefBranch.getBoolPref("devtools.tilt.enabled"); - info("originally: devtools.tilt.enabled = " + tiltEnabledOrig); + let netmonEnabledOrig = prefBranch.getBoolPref("devtools.netmonitor.enabled"); + info("originally: devtools.netmonitor.enabled = " + netmonEnabledOrig); yield helpers.audit(options, [ { @@ -66,11 +66,11 @@ function* spawnTest() { }, }, { - setup: 'pref show devtools.til', + setup: 'pref show devtools.netmoni', check: { - input: 'pref show devtools.til', - hints: 't.enabled', - markup: 'VVVVVVVVVVIIIIIIIIIIII', + input: 'pref show devtools.netmoni', + hints: 'tor.enabled', + markup: 'VVVVVVVVVVIIIIIIIIIIIIIIII', status: 'ERROR', tooltipState: 'true:importantFieldFlag', args: { @@ -79,32 +79,32 @@ function* spawnTest() { }, }, { - setup: 'pref reset devtools.tilt.enabled', + setup: 'pref reset devtools.netmonitor.enabled', check: { - input: 'pref reset devtools.tilt.enabled', + input: 'pref reset devtools.netmonitor.enabled', hints: '', - markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV', + markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV', status: 'VALID' }, }, { - setup: 'pref show devtools.tilt.enabled 4', + setup: 'pref show devtools.netmonitor.enabled 4', check: { - input: 'pref show devtools.tilt.enabled 4', + input: 'pref show devtools.netmonitor.enabled 4', hints: '', - markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVE', + markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVE', status: 'ERROR' }, }, { - setup: 'pref set devtools.tilt.enabled 4', + setup: 'pref set devtools.netmonitor.enabled 4', check: { - input: 'pref set devtools.tilt.enabled 4', + input: 'pref set devtools.netmonitor.enabled 4', hints: '', - markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVE', + markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVE', status: 'ERROR', args: { - setting: { arg: ' devtools.tilt.enabled' }, + setting: { arg: ' devtools.netmonitor.enabled' }, value: { status: 'ERROR', message: 'Can\'t use \'4\'.' }, } }, @@ -132,19 +132,19 @@ function* spawnTest() { }, }, { - setup: 'pref show devtools.tilt.enabled', + setup: 'pref show devtools.netmonitor.enabled', check: { args: { setting: { - value: options.requisition.system.settings.get("devtools.tilt.enabled") + value: options.requisition.system.settings.get("devtools.netmonitor.enabled") } }, }, exec: { - output: "devtools.tilt.enabled: " + tiltEnabledOrig, + output: "devtools.netmonitor.enabled: " + netmonEnabledOrig, }, post: function() { - prefBranch.setBoolPref("devtools.tilt.enabled", tiltEnabledOrig); + prefBranch.setBoolPref("devtools.netmonitor.enabled", netmonEnabledOrig); } }, ]); diff --git a/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js b/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js index ee9b4388ecd4..729405cb9e5f 100644 --- a/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js +++ b/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js @@ -81,12 +81,6 @@ function testToggleToolboxButtons() { let toolboxButtonNodes = [...doc.querySelectorAll(".command-button")]; let toggleableTools = toolbox.toolboxButtons; - // Tilt is disabled in E10S mode so we skip the tilt button if E10S is - // enabled. - if (toolbox.target.isMultiProcess) { - toolboxButtonNodes = [...doc.querySelectorAll(".command-button:not(#command-button-tilt)")]; - } - // The noautohide button is only displayed in the browser toolbox toggleableTools = toggleableTools.filter(tool => tool.id != "command-button-noautohide"); toolboxButtonNodes = toolboxButtonNodes.filter(btn => btn.id != "command-button-noautohide"); diff --git a/devtools/client/framework/toolbox-options.js b/devtools/client/framework/toolbox-options.js index 5ca4d61d6d08..66b3aa0a5864 100644 --- a/devtools/client/framework/toolbox-options.js +++ b/devtools/client/framework/toolbox-options.js @@ -174,9 +174,6 @@ OptionsPanel.prototype = { }; for (let tool of toggleableButtons) { - if (this.toolbox.target.isMultiProcess && tool.id === "command-button-tilt") { - continue; - } if (!tool.isTargetSupported(this.toolbox.target)) { continue; } diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 8f266fc51c37..c5b347ef3e6a 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -89,8 +89,6 @@ const ToolboxButtons = exports.ToolboxButtons = [ isTargetSupported: target => !target.isAddon }, { id: "command-button-responsive" }, { id: "command-button-paintflashing" }, - { id: "command-button-tilt", - commands: "devtools/client/tilt/tilt-commands" }, { id: "command-button-scratchpad" }, { id: "command-button-eyedropper" }, { id: "command-button-screenshot" }, @@ -1008,12 +1006,6 @@ Toolbox.prototype = { return false; } - // Disable tilt in E10S mode. Removing it from the list of toolbox buttons - // allows a bunch of tests to pass without modification. - if (this.target.isMultiProcess && options.id === "command-button-tilt") { - return false; - } - return { id: options.id, button: button, @@ -1050,22 +1042,6 @@ Toolbox.prototype = { }); this._updateNoautohideButton(); - - // Tilt is handled separately because it is disabled in E10S mode. Because - // we have removed tilt from toolboxButtons we have to deal with it here. - let tiltEnabled = !this.target.isMultiProcess && - Services.prefs.getBoolPref("devtools.command-button-tilt.enabled"); - let tiltButton = this.doc.getElementById("command-button-tilt"); - // Remote toolboxes don't add the button to the DOM at all - if (!tiltButton) { - return; - } - - if (tiltEnabled) { - tiltButton.removeAttribute("hidden"); - } else { - tiltButton.setAttribute("hidden", "true"); - } }, /** diff --git a/devtools/client/jar.mn b/devtools/client/jar.mn index 752d8402155f..4a1461457d21 100644 --- a/devtools/client/jar.mn +++ b/devtools/client/jar.mn @@ -177,8 +177,6 @@ devtools.jar: skin/images/command-responsivemode@2x.png (themes/images/command-responsivemode@2x.png) skin/images/command-scratchpad.png (themes/images/command-scratchpad.png) skin/images/command-scratchpad@2x.png (themes/images/command-scratchpad@2x.png) - skin/images/command-tilt.png (themes/images/command-tilt.png) - skin/images/command-tilt@2x.png (themes/images/command-tilt@2x.png) skin/images/command-pick.png (themes/images/command-pick.png) skin/images/command-pick@2x.png (themes/images/command-pick@2x.png) skin/images/command-frames.png (themes/images/command-frames.png) diff --git a/devtools/client/locales/en-US/tilt.properties b/devtools/client/locales/en-US/tilt.properties deleted file mode 100755 index 13d0293d016d..000000000000 --- a/devtools/client/locales/en-US/tilt.properties +++ /dev/null @@ -1,49 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# LOCALIZATION NOTE These strings are used inside the Tilt Inspector -# which is available from the Web Developer sub-menu -> 'Tilt'. -# -# The correct localization of this file might be to keep it in -# English, or another language commonly spoken among web developers. -# You want to make that choice consistent across the developer tools. -# A good criteria is the language in which you'd find the best -# documentation on web development on the web. - -# LOCALIZATION NOTE (initTilt.error): Tilt requires WebGL capabilities, which -# are not available on every hardware. This message is displayed as an modal -# popup window when initialization fails because of unsupported hardware. -initTilt.error = Could not initialize Tilt, please check the\ntroubleshooting information available at http://get.webgl.org/troubleshooting - -# LOCALIZATION NOTE (initWebGL.error): Tilt requires WebGL capabilities, which -# are not available on every hardware. This message is displayed in the console -# when initialization fails because of unsupported hardware. -initWebGL.error = Could not initialize the WebGL context, your hardware or drivers may not support it. - -# LOCALIZATION NOTE (linkProgram.error): This error happens when the WebGL -# context can't link two compiled shader programs together. It is displayed in -# the Error Console. -linkProgram.error = Could not initialize shader program: %S - -# LOCALIZATION NOTE (compileShader.source.error): This error is caused when the -# source (uri or path) of a shader is not the expected one. It is displayed in -# the Error Console. -compileShader.source.error = Bad shader source type (expected String). - -# LOCALIATION NOTE (compileShader.type.error): There are two types of shader -# programs - vertex and fragment. At a shader initialization, if none of these -# two types is specified, this compile-time error is shown. It is displayed in -# the Error Console. -compileShader.type.error = Wrong shader type specified for: %S - -# LOCALIZATION NOTE (compileShader.compile.error): If the shader source and -# type are correctly specified, there may be syntax errors in the shader code. -# If this is the case, this compile-time error is shown. It is displayed in -# the Error Console. -compileShader.compile.error = Shader compile status:\n%S - -# LOCALIZATION NOTE (compileShader.source.error): This error is caused when the -# source (canvas or image) of a texture is not as expected. It is displayed in -# the Error Console. -initTexture.source.error = Bad texture source type (expected Image). diff --git a/devtools/client/moz.build b/devtools/client/moz.build index 744eea327b1b..f6837ce6af94 100644 --- a/devtools/client/moz.build +++ b/devtools/client/moz.build @@ -33,7 +33,6 @@ DIRS += [ 'storage', 'styleeditor', 'themes', - 'tilt', 'webaudioeditor', 'webconsole', 'webide', diff --git a/devtools/client/preferences/devtools.js b/devtools/client/preferences/devtools.js index 86ca66d77e4b..a579ffdf3ce1 100644 --- a/devtools/client/preferences/devtools.js +++ b/devtools/client/preferences/devtools.js @@ -33,7 +33,7 @@ pref("devtools.toolbox.sidebar.width", 500); pref("devtools.toolbox.host", "bottom"); pref("devtools.toolbox.previousHost", "side"); pref("devtools.toolbox.selectedTool", "webconsole"); -pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","tilt toggle","scratchpad","resize toggle","eyedropper","screenshot --fullpage", "rulers", "measure"]'); +pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","scratchpad","resize toggle","eyedropper","screenshot --fullpage", "rulers", "measure"]'); pref("devtools.toolbox.sideEnabled", true); pref("devtools.toolbox.zoomValue", "1"); pref("devtools.toolbox.splitconsoleEnabled", false); @@ -44,7 +44,6 @@ pref("devtools.command-button-pick.enabled", true); pref("devtools.command-button-frames.enabled", true); pref("devtools.command-button-splitconsole.enabled", true); pref("devtools.command-button-paintflashing.enabled", false); -pref("devtools.command-button-tilt.enabled", false); pref("devtools.command-button-scratchpad.enabled", false); pref("devtools.command-button-responsive.enabled", true); pref("devtools.command-button-eyedropper.enabled", false); @@ -172,11 +171,6 @@ pref("devtools.netmonitor.har.forceExport", false); pref("devtools.netmonitor.har.pageLoadedTimeout", 1500); pref("devtools.netmonitor.har.enableAutoExportToFile", false); -// Enable the Tilt inspector -pref("devtools.tilt.enabled", true); -pref("devtools.tilt.intro_transition", true); -pref("devtools.tilt.outro_transition", true); - // Scratchpad settings // - recentFileMax: The maximum number of recently-opened files // stored. Setting this preference to 0 will not diff --git a/devtools/client/shared/telemetry.js b/devtools/client/shared/telemetry.js index 2532b00f04aa..8278ea7c9356 100644 --- a/devtools/client/shared/telemetry.js +++ b/devtools/client/shared/telemetry.js @@ -160,11 +160,6 @@ Telemetry.prototype = { userHistogram: "DEVTOOLS_STORAGE_OPENED_PER_USER_FLAG", timerHistogram: "DEVTOOLS_STORAGE_TIME_ACTIVE_SECONDS" }, - tilt: { - histogram: "DEVTOOLS_TILT_OPENED_COUNT", - userHistogram: "DEVTOOLS_TILT_OPENED_PER_USER_FLAG", - timerHistogram: "DEVTOOLS_TILT_TIME_ACTIVE_SECONDS" - }, paintflashing: { histogram: "DEVTOOLS_PAINTFLASHING_OPENED_COUNT", userHistogram: "DEVTOOLS_PAINTFLASHING_OPENED_PER_USER_FLAG", diff --git a/devtools/client/shared/test/browser.ini b/devtools/client/shared/test/browser.ini index 54df8e85ca3f..28eb25cab49e 100644 --- a/devtools/client/shared/test/browser.ini +++ b/devtools/client/shared/test/browser.ini @@ -136,9 +136,6 @@ skip-if = e10s # Bug 937167 - e10s paintflashing [browser_telemetry_button_responsive.js] skip-if = e10s # Bug 1067145 - e10s responsiveview [browser_telemetry_button_scratchpad.js] -[browser_telemetry_button_tilt.js] -skip-if = e10s # Bug 1086492 - Disable tilt for e10s - # Bug 937166 - Make tilt work in E10S mode [browser_telemetry_sidebar.js] [browser_telemetry_toolbox.js] [browser_telemetry_toolboxtabs_canvasdebugger.js] diff --git a/devtools/client/shared/test/browser_telemetry_button_tilt.js b/devtools/client/shared/test/browser_telemetry_button_tilt.js deleted file mode 100644 index 743ac5e97b71..000000000000 --- a/devtools/client/shared/test/browser_telemetry_button_tilt.js +++ /dev/null @@ -1,110 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -const TEST_URI = "data:text/html;charset=utf-8," + - "

browser_telemetry_button_tilt.js

"; - -// Because we need to gather stats for the period of time that a tool has been -// opened we make use of setTimeout() to create tool active times. -const TOOL_DELAY = 200; - -add_task(function*() { - yield addTab(TEST_URI); - let Telemetry = loadTelemetryAndRecordLogs(); - - let target = TargetFactory.forTab(gBrowser.selectedTab); - let toolbox = yield gDevTools.showToolbox(target, "inspector"); - - // Wait for the inspector to be initialized - yield toolbox.getPanel("inspector").once("inspector-updated"); - - info("inspector opened"); - - info("testing the tilt button"); - yield testButton(toolbox, Telemetry); - - stopRecordingTelemetryLogs(Telemetry); - - yield gDevTools.closeToolbox(target); - gBrowser.removeCurrentTab(); -}); - -function* testButton(toolbox, Telemetry) { - info("Testing command-button-tilt"); - - let button = toolbox.doc.querySelector("#command-button-tilt"); - ok(button, "Captain, we have the button"); - - yield delayedClicks(button, 4) - - checkResults("_TILT_", Telemetry); -} - -function delayedClicks(node, clicks) { - return new Promise(resolve => { - let clicked = 0; - - // See TOOL_DELAY for why we need setTimeout here - setTimeout(function delayedClick() { - if (clicked >= clicks) { - resolve(); - return; - } - info("Clicking button " + node.id); - - // Depending on odd/even click we are either opening - // or closing tilt - let event; - if (clicked % 2 == 0) { - info("Waiting for opening\n"); - event = "tilt-initialized"; - } else { - dump("Waiting for closing\n"); - event = "tilt-destroyed"; - } - let f = function () { - Services.obs.removeObserver(f, event, false); - setTimeout(delayedClick, 200); - }; - Services.obs.addObserver(f, event, false); - - clicked++; - node.click(); - }, TOOL_DELAY); - }); -} - -function checkResults(histIdFocus, Telemetry) { - let result = Telemetry.prototype.telemetryInfo; - - for (let [histId, value] of Iterator(result)) { - if (histId.startsWith("DEVTOOLS_INSPECTOR_") || - !histId.includes(histIdFocus)) { - // Inspector stats are tested in - // browser_telemetry_toolboxtabs_{toolname}.js so we skip them here - // because we only open the inspector once for this test. - continue; - } - - if (histId.endsWith("OPENED_PER_USER_FLAG")) { - ok(value.length === 1 && value[0] === true, - "Per user value " + histId + " has a single value of true"); - } else if (histId.endsWith("OPENED_COUNT")) { - ok(value.length > 1, histId + " has more than one entry"); - - let okay = value.every(function(element) { - return element === true; - }); - - ok(okay, "All " + histId + " entries are === true"); - } else if (histId.endsWith("TIME_ACTIVE_SECONDS")) { - ok(value.length > 1, histId + " has more than one entry"); - - let okay = value.every(function(element) { - return element > 0; - }); - - ok(okay, "All " + histId + " entries have time > 0"); - } - } -} diff --git a/devtools/client/themes/images/command-tilt.png b/devtools/client/themes/images/command-tilt.png deleted file mode 100644 index 841aac23f5292d3748ccf99b1ce469ca886afaca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 311 zcmV-70m%M|P)t3j)o9IK|#Upyb9QPfqkz6@$wJo(VK|DRI% zKrmy68yK+YtOP8&UUDq2RVm4ILy)AQOKGSZRNEn_fdRWEC{mV{OT>A{=I<@Ro(!${ zH=ZpXi_XD zI#KyK)_ceKuNC8!B>dPv#tt_y(Z1JJy-8AecPwoLGj`EA-V#Pe7W#HnbLjv8002ov JPDHLkV1gwPhB*KL diff --git a/devtools/client/themes/images/command-tilt@2x.png b/devtools/client/themes/images/command-tilt@2x.png deleted file mode 100644 index 8a13a9e08bf92f5163f0d190ed6bf8479771e3b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449 zcmV;y0Y3hTP)U~%4hj2SO-MFxJ7?9R^r?F=NUqij3@%q!zImGv>I{iT@JXs;4e_4=`*dig$@ zT%jxqM#xeQ<==LCdF!tRJ{1C_XndO3d>sI$0)wgmaIWV#f(b%t zofx;Rth@bJfHuHfV)8v@{XKh*excgBOKn{LuK?XHEGSbP;{MBEF4ZOv@)}944J>No zkMKZJ7U20EmbLXK*y`R;UP3jgcJ$k50nDbE+d=9k2asm@8s6*zzl)(8H>n2Iip0T> r=bCA=AOz##+sub(Jm1<}haf%y@p{anbWjIP00000NkvXXu0mjfa!$u> diff --git a/devtools/client/themes/toolbars.css b/devtools/client/themes/toolbars.css index 7e5d0793148c..8e473419dc8a 100644 --- a/devtools/client/themes/toolbars.css +++ b/devtools/client/themes/toolbars.css @@ -742,10 +742,6 @@ background-image: url("chrome://devtools/skin/images/command-responsivemode.png"); } -#command-button-tilt > image { - background-image: url("chrome://devtools/skin/images/command-tilt.png"); -} - #command-button-scratchpad > image { background-image: url("chrome://devtools/skin/images/command-scratchpad.png"); } @@ -791,10 +787,6 @@ background-image: url("chrome://devtools/skin/images/command-responsivemode@2x.png"); } - #command-button-tilt > image { - background-image: url("chrome://devtools/skin/images/command-tilt@2x.png"); - } - #command-button-scratchpad > image { background-image: url("chrome://devtools/skin/images/command-scratchpad@2x.png"); } diff --git a/devtools/client/tilt/TiltWorkerCrafter.js b/devtools/client/tilt/TiltWorkerCrafter.js deleted file mode 100644 index da31b5abf884..000000000000 --- a/devtools/client/tilt/TiltWorkerCrafter.js +++ /dev/null @@ -1,281 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -/** - * Given the initialization data (sizes and information about - * each DOM node) this worker sends back the arrays representing - * vertices, texture coords, colors, indices and all the needed data for - * rendering the DOM visualization mesh. - * - * Used in the TiltVisualization.Presenter object. - */ -self.onmessage = function TWC_onMessage(event) -{ - let data = event.data; - let maxGroupNodes = parseInt(data.maxGroupNodes); - let style = data.style; - let texWidth = data.texWidth; - let texHeight = data.texHeight; - let nodesInfo = data.nodesInfo; - - let mesh = { - allVertices: [], - groups: [], - width: 0, - height: 0 - }; - - let vertices; - let texCoord; - let color; - let stacksIndices; - let wireframeIndices; - let index; - - // seed the random function to get the same values each time - // we're doing this to avoid ugly z-fighting with overlapping nodes - self.random.seed(0); - - // go through all the dom nodes and compute the verts, texcoord etc. - for (let n = 0, len = nodesInfo.length; n < len; n++) { - - // check if we need to start creating a new group - if (n % maxGroupNodes === 0) { - vertices = []; // recreate the arrays used to construct the 3D mesh data - texCoord = []; - color = []; - stacksIndices = []; - wireframeIndices = []; - index = 0; - } - - let info = nodesInfo[n]; - let coord = info.coord; - - // calculate the stack x, y, z, width and height coordinates - let z = coord.depth + coord.thickness; - let y = coord.top; - let x = coord.left; - let w = coord.width; - let h = coord.height; - - // the maximum texture size slices the visualization mesh where needed - if (x + w > texWidth) { - w = texWidth - x; - } - if (y + h > texHeight) { - h = texHeight - y; - } - - x += self.random.next(); - y += self.random.next(); - w -= self.random.next() * 0.1; - h -= self.random.next() * 0.1; - - let xpw = x + w; - let yph = y + h; - let zmt = coord.depth; - - let xotw = x / texWidth; - let yoth = y / texHeight; - let xpwotw = xpw / texWidth; - let yphoth = yph / texHeight; - - // calculate the margin fill color - let fill = style[info.name] || style.highlight.defaultFill; - - let r = fill[0]; - let g = fill[1]; - let b = fill[2]; - let g10 = r * 1.1; - let g11 = g * 1.1; - let g12 = b * 1.1; - let g20 = r * 0.6; - let g21 = g * 0.6; - let g22 = b * 0.6; - - // compute the vertices - vertices.push(x, y, z, /* front */ // 0 - x, yph, z, // 1 - xpw, yph, z, // 2 - xpw, y, z, // 3 - // we don't duplicate vertices for the left and right faces, because - // they can be reused from the bottom and top faces; we do, however, - // duplicate some vertices from front face, because it has custom - // texture coordinates which are not shared by the other faces - x, y, z, /* front */ // 4 - x, yph, z, // 5 - xpw, yph, z, // 6 - xpw, y, z, // 7 - x, y, zmt, /* back */ // 8 - x, yph, zmt, // 9 - xpw, yph, zmt, // 10 - xpw, y, zmt); // 11 - - // compute the texture coordinates - texCoord.push(xotw, yoth, - xotw, yphoth, - xpwotw, yphoth, - xpwotw, yoth, - -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0); - - // compute the colors for each vertex in the mesh - color.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - g10, g11, g12, - g10, g11, g12, - g10, g11, g12, - g10, g11, g12, - g20, g21, g22, - g20, g21, g22, - g20, g21, g22, - g20, g21, g22); - - let i = index; // number of vertex points, used to create the indices array - let ip1 = i + 1; - let ip2 = ip1 + 1; - let ip3 = ip2 + 1; - let ip4 = ip3 + 1; - let ip5 = ip4 + 1; - let ip6 = ip5 + 1; - let ip7 = ip6 + 1; - let ip8 = ip7 + 1; - let ip9 = ip8 + 1; - let ip10 = ip9 + 1; - let ip11 = ip10 + 1; - - // compute the stack indices - stacksIndices.unshift(i, ip1, ip2, i, ip2, ip3, - ip8, ip9, ip5, ip8, ip5, ip4, - ip7, ip6, ip10, ip7, ip10, ip11, - ip8, ip4, ip7, ip8, ip7, ip11, - ip5, ip9, ip10, ip5, ip10, ip6); - - // compute the wireframe indices - if (coord.thickness !== 0) { - wireframeIndices.unshift(i, ip1, ip1, ip2, - ip2, ip3, ip3, i, - ip8, i, ip9, ip1, - ip11, ip3, ip10, ip2); - } - - // there are 12 vertices in a stack representing a node - index += 12; - - // set the maximum mesh width and height to calculate the center offset - mesh.width = Math.max(w, mesh.width); - mesh.height = Math.max(h, mesh.height); - - // check if we need to save the currently active group; this happens after - // we filled all the "slots" in a group or there aren't any remaining nodes - if (((n + 1) % maxGroupNodes === 0) || (n === len - 1)) { - mesh.groups.push({ - vertices: vertices, - texCoord: texCoord, - color: color, - stacksIndices: stacksIndices, - wireframeIndices: wireframeIndices - }); - mesh.allVertices = mesh.allVertices.concat(vertices); - } - } - - self.postMessage(mesh); - close(); -}; - -/** - * Utility functions for generating random numbers using the Alea algorithm. - */ -self.random = { - - /** - * The generator function, automatically created with seed 0. - */ - _generator: null, - - /** - * Returns a new random number between [0..1) - */ - next: function RNG_next() - { - return this._generator(); - }, - - /** - * From http://baagoe.com/en/RandomMusings/javascript - * Johannes Baagoe , 2010 - * - * Seeds a random generator function with a set of passed arguments. - */ - seed: function RNG_seed() - { - let s0 = 0; - let s1 = 0; - let s2 = 0; - let c = 1; - - if (arguments.length === 0) { - return this.seed(+new Date()); - } else { - s0 = this.mash(" "); - s1 = this.mash(" "); - s2 = this.mash(" "); - - for (let i = 0, len = arguments.length; i < len; i++) { - s0 -= this.mash(arguments[i]); - if (s0 < 0) { - s0 += 1; - } - s1 -= this.mash(arguments[i]); - if (s1 < 0) { - s1 += 1; - } - s2 -= this.mash(arguments[i]); - if (s2 < 0) { - s2 += 1; - } - } - - let random = function() { - let t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32 - s0 = s1; - s1 = s2; - return (s2 = t - (c = t | 0)); - }; - random.uint32 = function() { - return random() * 0x100000000; // 2^32 - }; - random.fract53 = function() { - return random() + - (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 - }; - return (this._generator = random); - } - }, - - /** - * From http://baagoe.com/en/RandomMusings/javascript - * Johannes Baagoe , 2010 - */ - mash: function RNG_mash(data) - { - let h, n = 0xefc8249d; - - data = data.toString(); - for (let i = 0, len = data.length; i < len; i++) { - n += data.charCodeAt(i); - h = 0.02519603282416938 * n; - n = h >>> 0; - h -= n; - h *= n; - n = h >>> 0; - h -= n; - n += h * 0x100000000; // 2^32 - } - return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 - } -}; diff --git a/devtools/client/tilt/TiltWorkerPicker.js b/devtools/client/tilt/TiltWorkerPicker.js deleted file mode 100644 index 98ab5131c6f3..000000000000 --- a/devtools/client/tilt/TiltWorkerPicker.js +++ /dev/null @@ -1,186 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -/** - * This worker handles picking, given a set of vertices and a ray (calculates - * the intersection points and offers back information about the closest hit). - * - * Used in the TiltVisualization.Presenter object. - */ -self.onmessage = function TWP_onMessage(event) -{ - let data = event.data; - let vertices = data.vertices; - let ray = data.ray; - - let intersection = null; - let hit = []; - - // calculates the squared distance between two points - function dsq(p1, p2) { - let xd = p2[0] - p1[0]; - let yd = p2[1] - p1[1]; - let zd = p2[2] - p1[2]; - - return xd * xd + yd * yd + zd * zd; - } - - // check each stack face in the visualization mesh for intersections with - // the mouse ray (using a ray picking algorithm) - for (let i = 0, len = vertices.length; i < len; i += 36) { - - // the front quad - let v0f = [vertices[i], vertices[i + 1], vertices[i + 2]]; - let v1f = [vertices[i + 3], vertices[i + 4], vertices[i + 5]]; - let v2f = [vertices[i + 6], vertices[i + 7], vertices[i + 8]]; - let v3f = [vertices[i + 9], vertices[i + 10], vertices[i + 11]]; - - // the back quad - let v0b = [vertices[i + 24], vertices[i + 25], vertices[i + 26]]; - let v1b = [vertices[i + 27], vertices[i + 28], vertices[i + 29]]; - let v2b = [vertices[i + 30], vertices[i + 31], vertices[i + 32]]; - let v3b = [vertices[i + 33], vertices[i + 34], vertices[i + 35]]; - - // don't do anything with degenerate quads - if (!v0f[0] && !v1f[0] && !v2f[0] && !v3f[0]) { - continue; - } - - // for each triangle in the stack box, check for the intersections - if (self.intersect(v0f, v1f, v2f, ray, hit) || // front left - self.intersect(v0f, v2f, v3f, ray, hit) || // front right - self.intersect(v0b, v1b, v1f, ray, hit) || // left back - self.intersect(v0b, v1f, v0f, ray, hit) || // left front - self.intersect(v3f, v2b, v3b, ray, hit) || // right back - self.intersect(v3f, v2f, v2b, ray, hit) || // right front - self.intersect(v0b, v0f, v3f, ray, hit) || // top left - self.intersect(v0b, v3f, v3b, ray, hit) || // top right - self.intersect(v1f, v1b, v2b, ray, hit) || // bottom left - self.intersect(v1f, v2b, v2f, ray, hit)) { // bottom right - - // calculate the distance between the intersection hit point and camera - let d = dsq(hit, ray.origin); - - // we're picking the closest stack in the mesh from the camera - if (intersection === null || d < intersection.distance) { - intersection = { - // each mesh stack is composed of 12 vertices, so there's information - // about a node once in 12 * 3 = 36 iterations (to avoid duplication) - index: i / 36, - distance: d - }; - } - } - } - - self.postMessage(intersection); - close(); -}; - -/** - * Utility function for finding intersections between a ray and a triangle. - */ -self.intersect = (function() { - - // creates a new instance of a vector - function create() { - return new Float32Array(3); - } - - // performs a vector addition - function add(aVec, aVec2, aDest) { - aDest[0] = aVec[0] + aVec2[0]; - aDest[1] = aVec[1] + aVec2[1]; - aDest[2] = aVec[2] + aVec2[2]; - return aDest; - } - - // performs a vector subtraction - function subtract(aVec, aVec2, aDest) { - aDest[0] = aVec[0] - aVec2[0]; - aDest[1] = aVec[1] - aVec2[1]; - aDest[2] = aVec[2] - aVec2[2]; - return aDest; - } - - // performs a vector scaling - function scale(aVec, aVal, aDest) { - aDest[0] = aVec[0] * aVal; - aDest[1] = aVec[1] * aVal; - aDest[2] = aVec[2] * aVal; - return aDest; - } - - // generates the cross product of two vectors - function cross(aVec, aVec2, aDest) { - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - let x2 = aVec2[0]; - let y2 = aVec2[1]; - let z2 = aVec2[2]; - - aDest[0] = y * z2 - z * y2; - aDest[1] = z * x2 - x * z2; - aDest[2] = x * y2 - y * x2; - return aDest; - } - - // calculates the dot product of two vectors - function dot(aVec, aVec2) { - return aVec[0] * aVec2[0] + aVec[1] * aVec2[1] + aVec[2] * aVec2[2]; - } - - let edge1 = create(); - let edge2 = create(); - let pvec = create(); - let tvec = create(); - let qvec = create(); - let lvec = create(); - - // checks for ray-triangle intersections using the Fast Minimum-Storage - // (simplified) algorithm by Tomas Moller and Ben Trumbore - return function intersect(aVert0, aVert1, aVert2, aRay, aDest) { - let dir = aRay.direction; - let orig = aRay.origin; - - // find vectors for two edges sharing vert0 - subtract(aVert1, aVert0, edge1); - subtract(aVert2, aVert0, edge2); - - // begin calculating determinant - also used to calculate the U parameter - cross(dir, edge2, pvec); - - // if determinant is near zero, ray lines in plane of triangle - let inv_det = 1 / dot(edge1, pvec); - - // calculate distance from vert0 to ray origin - subtract(orig, aVert0, tvec); - - // calculate U parameter and test bounds - let u = dot(tvec, pvec) * inv_det; - if (u < 0 || u > 1) { - return false; - } - - // prepare to test V parameter - cross(tvec, edge1, qvec); - - // calculate V parameter and test bounds - let v = dot(dir, qvec) * inv_det; - if (v < 0 || u + v > 1) { - return false; - } - - // calculate T, ray intersects triangle - let t = dot(edge2, qvec) * inv_det; - - scale(dir, t, lvec); - add(orig, lvec, aDest); - return true; - }; -}()); diff --git a/devtools/client/tilt/moz.build b/devtools/client/tilt/moz.build deleted file mode 100644 index 86037f6bd859..000000000000 --- a/devtools/client/tilt/moz.build +++ /dev/null @@ -1,17 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DevToolsModules( - 'tilt-commands.js', - 'tilt-gl.js', - 'tilt-math.js', - 'tilt-utils.js', - 'tilt-visualizer-style.js', - 'tilt-visualizer.js', - 'tilt.js', - 'TiltWorkerCrafter.js', - 'TiltWorkerPicker.js' -) - -BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] diff --git a/devtools/client/tilt/test/.eslintrc b/devtools/client/tilt/test/.eslintrc deleted file mode 100644 index 044c3e4f49e8..000000000000 --- a/devtools/client/tilt/test/.eslintrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - // Extend from the shared list of defined globals for mochitests. - "extends": "../../../.eslintrc.mochitests" -} diff --git a/devtools/client/tilt/test/browser.ini b/devtools/client/tilt/test/browser.ini deleted file mode 100644 index 5da2cb45df70..000000000000 --- a/devtools/client/tilt/test/browser.ini +++ /dev/null @@ -1,54 +0,0 @@ -[DEFAULT] -tags = devtools -skip-if = e10s # Bug 1086492 - Disable tilt for e10s - # Bug 937166 - Make tilt work in E10S mode -subsuite = devtools -support-files = head.js - -[browser_tilt_01_lazy_getter.js] -[browser_tilt_02_notifications-seq.js] -[browser_tilt_02_notifications-tabs.js] -[browser_tilt_02_notifications.js] -[browser_tilt_03_tab_switch.js] -skip-if = true # Bug 1093215 - Failed assertion -[browser_tilt_04_initialization.js] -[browser_tilt_05_destruction-esc.js] -[browser_tilt_05_destruction-url.js] -[browser_tilt_05_destruction.js] -[browser_tilt_arcball-reset-typeahead.js] -[browser_tilt_arcball-reset.js] -[browser_tilt_arcball.js] -[browser_tilt_controller.js] -[browser_tilt_gl01.js] -[browser_tilt_gl02.js] -[browser_tilt_gl03.js] -[browser_tilt_gl04.js] -[browser_tilt_gl05.js] -[browser_tilt_gl06.js] -[browser_tilt_gl07.js] -[browser_tilt_gl08.js] -[browser_tilt_math01.js] -[browser_tilt_math02.js] -[browser_tilt_math03.js] -[browser_tilt_math04.js] -[browser_tilt_math05.js] -[browser_tilt_math06.js] -[browser_tilt_math07.js] -[browser_tilt_picking.js] -[browser_tilt_picking_delete.js] -[browser_tilt_picking_highlight01-offs.js] -[browser_tilt_picking_highlight01.js] -[browser_tilt_picking_highlight02.js] -[browser_tilt_picking_highlight03.js] -[browser_tilt_picking_inspector.js] -[browser_tilt_picking_miv.js] -[browser_tilt_utils01.js] -[browser_tilt_utils02.js] -[browser_tilt_utils03.js] -[browser_tilt_utils04.js] -[browser_tilt_utils05.js] -[browser_tilt_utils06.js] -[browser_tilt_utils07.js] -[browser_tilt_utils08.js] -[browser_tilt_visualizer.js] -[browser_tilt_zoom.js] diff --git a/devtools/client/tilt/test/browser_tilt_01_lazy_getter.js b/devtools/client/tilt/test/browser_tilt_01_lazy_getter.js deleted file mode 100644 index de77ccb90c93..000000000000 --- a/devtools/client/tilt/test/browser_tilt_01_lazy_getter.js +++ /dev/null @@ -1,14 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - ok(Tilt, - "The Tilt object wasn't got correctly via defineLazyGetter."); - is(Tilt.chromeWindow, window, - "The top-level window wasn't saved correctly"); - ok(Tilt.visualizers, - "The holder object for all the instances of the visualizer doesn't exist.") - ok(Tilt.NOTIFICATIONS, - "The notifications constants weren't referenced correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_02_notifications-seq.js b/devtools/client/tilt/test/browser_tilt_02_notifications-seq.js deleted file mode 100644 index 6c4a40a5e66f..000000000000 --- a/devtools/client/tilt/test/browser_tilt_02_notifications-seq.js +++ /dev/null @@ -1,99 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tabEvents = ""; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping notifications test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping notifications test because WebGL isn't supported."); - return; - } - - requestLongerTimeout(10); - waitForExplicitFinish(); - - createTab(function() { - Services.obs.addObserver(finalize, DESTROYED, false); - Services.obs.addObserver(obs_STARTUP, STARTUP, false); - Services.obs.addObserver(obs_INITIALIZING, INITIALIZING, false); - Services.obs.addObserver(obs_INITIALIZED, INITIALIZED, false); - Services.obs.addObserver(obs_DESTROYING, DESTROYING, false); - Services.obs.addObserver(obs_BEFORE_DESTROYED, BEFORE_DESTROYED, false); - Services.obs.addObserver(obs_DESTROYED, DESTROYED, false); - - info("Starting up the Tilt notifications test."); - createTilt({}, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function obs_STARTUP(win) { - info("Handling the STARTUP notification."); - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "STARTUP;"; -} - -function obs_INITIALIZING(win) { - info("Handling the INITIALIZING notification."); - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "INITIALIZING;"; -} - -function obs_INITIALIZED(win) { - info("Handling the INITIALIZED notification."); - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "INITIALIZED;"; - - Tilt.destroy(Tilt.currentWindowId, true); -} - -function obs_DESTROYING(win) { - info("Handling the DESTROYING( notification."); - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "DESTROYING;"; -} - -function obs_BEFORE_DESTROYED(win) { - info("Handling the BEFORE_DESTROYED notification."); - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "BEFORE_DESTROYED;"; -} - -function obs_DESTROYED(win) { - info("Handling the DESTROYED notification."); - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "DESTROYED;"; -} - -function finalize(win) { - is(win, gBrowser.selectedBrowser.contentWindow, "Saw the correct window"); - is(tabEvents, "STARTUP;INITIALIZING;INITIALIZED;DESTROYING;BEFORE_DESTROYED;DESTROYED;", - "The notifications weren't fired in the correct order."); - - cleanup(); -} - -function cleanup() { - info("Cleaning up the notifications test."); - - Services.obs.removeObserver(finalize, DESTROYED); - Services.obs.removeObserver(obs_INITIALIZING, INITIALIZING); - Services.obs.removeObserver(obs_INITIALIZED, INITIALIZED); - Services.obs.removeObserver(obs_DESTROYING, DESTROYING); - Services.obs.removeObserver(obs_BEFORE_DESTROYED, BEFORE_DESTROYED); - Services.obs.removeObserver(obs_DESTROYED, DESTROYED); - Services.obs.removeObserver(obs_STARTUP, STARTUP); - - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_02_notifications-tabs.js b/devtools/client/tilt/test/browser_tilt_02_notifications-tabs.js deleted file mode 100644 index 9ca5c18c6e2b..000000000000 --- a/devtools/client/tilt/test/browser_tilt_02_notifications-tabs.js +++ /dev/null @@ -1,179 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tab0, tab1, tab2; -var testStep = -1; - -var expected = []; -function expect(notification, win) { - expected.push({ notification: notification, window: win }); -} - -function notification(win, topic) { - if (expected.length == 0) { - is(topic, null, "Shouldn't see a notification"); - return; - } - - let { notification, window } = expected.shift(); - if (Cu.isDeadWrapper(window)) { - // Sometimes we end up with a nuked window reference here :-( - return; - } - is(topic, notification, "Saw the expected notification"); - is(win, window, "Saw the expected window"); -} - -function after(notification, callback) { - function observer() { - Services.obs.removeObserver(observer, notification); - executeSoon(callback); - } - Services.obs.addObserver(observer, notification, false); -} - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping tab switch test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping tab switch test because WebGL isn't supported."); - return; - } - - Services.obs.addObserver(notification, STARTUP, false); - Services.obs.addObserver(notification, INITIALIZING, false); - Services.obs.addObserver(notification, INITIALIZED, false); - Services.obs.addObserver(notification, DESTROYING, false); - Services.obs.addObserver(notification, BEFORE_DESTROYED, false); - Services.obs.addObserver(notification, DESTROYED, false); - Services.obs.addObserver(notification, SHOWN, false); - Services.obs.addObserver(notification, HIDDEN, false); - - waitForExplicitFinish(); - - tab0 = gBrowser.selectedTab; - nextStep(); -} - -function createTab2() { -} - -var testSteps = [ - function step0() { - tab1 = createTab(function() { - expect(STARTUP, tab1.linkedBrowser.contentWindow); - expect(INITIALIZING, tab1.linkedBrowser.contentWindow); - expect(INITIALIZED, tab1.linkedBrowser.contentWindow); - after(INITIALIZED, nextStep); - - createTilt({}, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); - }, - function step1() { - expect(HIDDEN, tab1.linkedBrowser.contentWindow); - - tab2 = createTab(function() { - expect(STARTUP, tab2.linkedBrowser.contentWindow); - expect(INITIALIZING, tab2.linkedBrowser.contentWindow); - expect(INITIALIZED, tab2.linkedBrowser.contentWindow); - after(INITIALIZED, nextStep); - - createTilt({}, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); - }, - function step2() { - expect(HIDDEN, tab2.linkedBrowser.contentWindow); - after(HIDDEN, nextStep); - - gBrowser.selectedTab = tab0; - }, - function step3() { - expect(SHOWN, tab2.linkedBrowser.contentWindow); - after(SHOWN, nextStep); - - gBrowser.selectedTab = tab2; - }, - function step4() { - expect(HIDDEN, tab2.linkedBrowser.contentWindow); - expect(SHOWN, tab1.linkedBrowser.contentWindow); - after(SHOWN, nextStep); - - gBrowser.selectedTab = tab1; - }, - function step5() { - expect(HIDDEN, tab1.linkedBrowser.contentWindow); - expect(SHOWN, tab2.linkedBrowser.contentWindow); - after(SHOWN, nextStep); - - gBrowser.selectedTab = tab2; - }, - function step6() { - expect(DESTROYING, tab2.linkedBrowser.contentWindow); - expect(BEFORE_DESTROYED, tab2.linkedBrowser.contentWindow); - expect(DESTROYED, tab2.linkedBrowser.contentWindow); - after(DESTROYED, nextStep); - - Tilt.destroy(Tilt.currentWindowId, true); - }, - function step7() { - expect(SHOWN, tab1.linkedBrowser.contentWindow); - - gBrowser.removeCurrentTab(); - tab2 = null; - - expect(DESTROYING, tab1.linkedBrowser.contentWindow); - expect(HIDDEN, tab1.linkedBrowser.contentWindow); - expect(BEFORE_DESTROYED, tab1.linkedBrowser.contentWindow); - expect(DESTROYED, tab1.linkedBrowser.contentWindow); - after(DESTROYED, nextStep); - - gBrowser.removeCurrentTab(); - tab1 = null; - }, - function step8_cleanup() { - is(gBrowser.selectedTab, tab0, "Should be back to the first tab"); - - cleanup(); - } -]; - -function cleanup() { - if (tab1) { - gBrowser.removeTab(tab1); - tab1 = null; - } - if (tab2) { - gBrowser.removeTab(tab2); - tab2 = null; - } - - Services.obs.removeObserver(notification, STARTUP); - Services.obs.removeObserver(notification, INITIALIZING); - Services.obs.removeObserver(notification, INITIALIZED); - Services.obs.removeObserver(notification, DESTROYING); - Services.obs.removeObserver(notification, BEFORE_DESTROYED); - Services.obs.removeObserver(notification, DESTROYED); - Services.obs.removeObserver(notification, SHOWN); - Services.obs.removeObserver(notification, HIDDEN); - - finish(); -} - -function nextStep() { - let step = testSteps.shift(); - info("Executing " + step.name); - step(); -} diff --git a/devtools/client/tilt/test/browser_tilt_02_notifications.js b/devtools/client/tilt/test/browser_tilt_02_notifications.js deleted file mode 100644 index a0f768d3290f..000000000000 --- a/devtools/client/tilt/test/browser_tilt_02_notifications.js +++ /dev/null @@ -1,131 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tab0, tab1; -var testStep = -1; -var tabEvents = ""; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping notifications test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping notifications test because WebGL isn't supported."); - return; - } - - requestLongerTimeout(10); - waitForExplicitFinish(); - - gBrowser.tabContainer.addEventListener("TabSelect", tabSelect, false); - createNewTab(); -} - -function createNewTab() { - tab0 = gBrowser.selectedTab; - - tab1 = createTab(function() { - Services.obs.addObserver(finalize, DESTROYED, false); - Services.obs.addObserver(tab_STARTUP, STARTUP, false); - Services.obs.addObserver(tab_INITIALIZING, INITIALIZING, false); - Services.obs.addObserver(tab_DESTROYING, DESTROYING, false); - Services.obs.addObserver(tab_SHOWN, SHOWN, false); - Services.obs.addObserver(tab_HIDDEN, HIDDEN, false); - - info("Starting up the Tilt notifications test."); - createTilt({ - onTiltOpen: function() - { - testStep = 0; - tabSelect(); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function tab_STARTUP(win) { - info("Handling the STARTUP notification."); - is(win, tab1.linkedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "STARTUP;"; -} - -function tab_INITIALIZING(win) { - info("Handling the INITIALIZING notification."); - is(win, tab1.linkedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "INITIALIZING;"; -} - -function tab_DESTROYING(win) { - info("Handling the DESTROYING notification."); - is(win, tab1.linkedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "DESTROYING;"; -} - -function tab_SHOWN(win) { - info("Handling the SHOWN notification."); - is(win, tab1.linkedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "SHOWN;"; -} - -function tab_HIDDEN(win) { - info("Handling the HIDDEN notification."); - is(win, tab1.linkedBrowser.contentWindow, "Saw the correct window"); - tabEvents += "HIDDEN;"; -} - -var testSteps = [ - function step0() { - info("Selecting tab0."); - gBrowser.selectedTab = tab0; - }, - function step1() { - info("Selecting tab1."); - gBrowser.selectedTab = tab1; - }, - function step2() { - info("Killing it."); - Tilt.destroy(Tilt.currentWindowId, true); - } -]; - -function finalize(win) { - is(win, tab1.linkedBrowser.contentWindow, "Saw the correct window"); - - is(tabEvents, "STARTUP;INITIALIZING;HIDDEN;SHOWN;DESTROYING;", - "The notifications weren't fired in the correct order."); - - cleanup(); -} - -function cleanup() { - info("Cleaning up the notifications test."); - - tab0 = null; - tab1 = null; - - Services.obs.removeObserver(finalize, DESTROYED); - Services.obs.removeObserver(tab_INITIALIZING, INITIALIZING); - Services.obs.removeObserver(tab_DESTROYING, DESTROYING); - Services.obs.removeObserver(tab_SHOWN, SHOWN); - Services.obs.removeObserver(tab_HIDDEN, HIDDEN); - Services.obs.removeObserver(tab_STARTUP, STARTUP); - - gBrowser.tabContainer.removeEventListener("TabSelect", tabSelect); - gBrowser.removeCurrentTab(); - finish(); -} - -function tabSelect() { - if (testStep !== -1) { - executeSoon(testSteps[testStep]); - testStep++; - } -} diff --git a/devtools/client/tilt/test/browser_tilt_03_tab_switch.js b/devtools/client/tilt/test/browser_tilt_03_tab_switch.js deleted file mode 100644 index 8e60824e7a41..000000000000 --- a/devtools/client/tilt/test/browser_tilt_03_tab_switch.js +++ /dev/null @@ -1,110 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tab0, tab1, tab2; -var testStep = -1; - -function test() { - // This test relies on a timeout to indicate pass or fail. All tests need at - // least one pass, fail or todo so let's create a dummy pass. - ok(true, "Each test requires at least one pass, fail or todo so here is a pass."); - - if (!isTiltEnabled()) { - info("Skipping tab switch test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - info("Skipping tab switch test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - gBrowser.tabContainer.addEventListener("TabSelect", tabSelect, false); - createTab1(); -} - -function createTab1() { - tab0 = gBrowser.selectedTab; - - tab1 = createTab(function() { - createTilt({ - onTiltOpen: function() - { - createTab2(); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function createTab2() { - tab2 = createTab(function() { - - createTilt({ - onTiltOpen: function() - { - testStep = 0; - tabSelect(); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -var testSteps = [ - function step0() { - gBrowser.selectedTab = tab1; - }, - function step1() { - gBrowser.selectedTab = tab0; - }, - function step2() { - gBrowser.selectedTab = tab1; - }, - function step3() { - gBrowser.selectedTab = tab2; - }, - function step4() { - Tilt.destroy(Tilt.currentWindowId); - gBrowser.removeCurrentTab(); - tab2 = null; - }, - function step5() { - Tilt.destroy(Tilt.currentWindowId); - gBrowser.removeCurrentTab(); - tab1 = null; - }, - function step6_cleanup() { - cleanup(); - } -]; - -function cleanup() { - gBrowser.tabContainer.removeEventListener("TabSelect", tabSelect, false); - - if (tab1) { - gBrowser.removeTab(tab1); - tab1 = null; - } - if (tab2) { - gBrowser.removeTab(tab2); - tab2 = null; - } - - finish(); -} - -function tabSelect() { - if (testStep !== -1) { - executeSoon(testSteps[testStep]); - testStep++; - } -} diff --git a/devtools/client/tilt/test/browser_tilt_04_initialization.js b/devtools/client/tilt/test/browser_tilt_04_initialization.js deleted file mode 100644 index da0a936a262e..000000000000 --- a/devtools/client/tilt/test/browser_tilt_04_initialization.js +++ /dev/null @@ -1,59 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping initialization test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping initialization test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - let id = TiltUtils.getWindowId(gBrowser.selectedBrowser.contentWindow); - - is(id, Tilt.currentWindowId, - "The unique window identifiers should match for the same window."); - - createTilt({ - onTiltOpen: function(instance) - { - is(document.activeElement, instance.presenter.canvas, - "The visualizer canvas should be focused on initialization."); - - ok(Tilt.visualizers[id] instanceof TiltVisualizer, - "A new instance of the visualizer wasn't created properly."); - ok(Tilt.visualizers[id].isInitialized(), - "The new instance of the visualizer wasn't initialized properly."); - }, - onTiltClose: function() - { - is(document.activeElement, gBrowser.selectedBrowser, - "The focus wasn't correctly given back to the selectedBrowser."); - - is(Tilt.visualizers[id], null, - "The current instance of the visualizer wasn't destroyed properly."); - }, - onEnd: function() - { - cleanup(); - } - }, true, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function cleanup() { - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_05_destruction-esc.js b/devtools/client/tilt/test/browser_tilt_05_destruction-esc.js deleted file mode 100644 index 5a8bf8a70669..000000000000 --- a/devtools/client/tilt/test/browser_tilt_05_destruction-esc.js +++ /dev/null @@ -1,51 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tiltOpened = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping destruction test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping destruction test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function() - { - tiltOpened = true; - - Services.obs.addObserver(finalize, DESTROYED, false); - EventUtils.sendKey("ESCAPE"); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function finalize() { - let id = TiltUtils.getWindowId(gBrowser.selectedBrowser.contentWindow); - - is(Tilt.visualizers[id], null, - "The current instance of the visualizer wasn't destroyed properly."); - - cleanup(); -} - -function cleanup() { - if (tiltOpened) { Services.obs.removeObserver(finalize, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_05_destruction-url.js b/devtools/client/tilt/test/browser_tilt_05_destruction-url.js deleted file mode 100644 index a2a2c4571c3c..000000000000 --- a/devtools/client/tilt/test/browser_tilt_05_destruction-url.js +++ /dev/null @@ -1,51 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tiltOpened = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping destruction test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping destruction test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function() - { - tiltOpened = true; - - Services.obs.addObserver(finalize, DESTROYED, false); - window.content.location = "about:mozilla"; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function finalize() { - let id = TiltUtils.getWindowId(gBrowser.selectedBrowser.contentWindow); - - is(Tilt.visualizers[id], null, - "The current instance of the visualizer wasn't destroyed properly."); - - cleanup(); -} - -function cleanup() { - if (tiltOpened) { Services.obs.removeObserver(finalize, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_05_destruction.js b/devtools/client/tilt/test/browser_tilt_05_destruction.js deleted file mode 100644 index dec188049209..000000000000 --- a/devtools/client/tilt/test/browser_tilt_05_destruction.js +++ /dev/null @@ -1,51 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tiltOpened = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping destruction test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping destruction test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function() - { - tiltOpened = true; - - Services.obs.addObserver(finalize, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function finalize() { - let id = TiltUtils.getWindowId(gBrowser.selectedBrowser.contentWindow); - - is(Tilt.visualizers[id], null, - "The current instance of the visualizer wasn't destroyed properly."); - - cleanup(); -} - -function cleanup() { - if (tiltOpened) { Services.obs.removeObserver(finalize, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_arcball-reset-typeahead.js b/devtools/client/tilt/test/browser_tilt_arcball-reset-typeahead.js deleted file mode 100644 index 91f8f4d6acde..000000000000 --- a/devtools/client/tilt/test/browser_tilt_arcball-reset-typeahead.js +++ /dev/null @@ -1,132 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tiltOpened = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping part of the arcball test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping part of the arcball test because WebGL isn't supported."); - return; - } - - requestLongerTimeout(10); - waitForExplicitFinish(); - Services.prefs.setBoolPref("accessibility.typeaheadfind", true); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - tiltOpened = true; - - performTest(instance.presenter.canvas, - instance.controller.arcball, function() { - - info("Killing arcball reset test."); - - Services.prefs.setBoolPref("accessibility.typeaheadfind", false); - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function performTest(canvas, arcball, callback) { - is(document.activeElement, canvas, - "The visualizer canvas should be focused when performing this test."); - - info("Starting arcball reset test."); - - // start translating and rotating sometime at random - - window.setTimeout(function() { - info("Synthesizing key down events."); - - EventUtils.synthesizeKey("VK_S", { type: "keydown" }); // add a little - EventUtils.synthesizeKey("VK_RIGHT", { type: "keydown" }); // diversity - - // wait for some arcball translations and rotations to happen - - window.setTimeout(function() { - info("Synthesizing key up events."); - - EventUtils.synthesizeKey("VK_S", { type: "keyup" }); - EventUtils.synthesizeKey("VK_RIGHT", { type: "keyup" }); - - // ok, transformations finished, we can now try to reset the model view - - window.setTimeout(function() { - info("Synthesizing arcball reset key press."); - - arcball._onResetStart = function() { - info("Starting arcball reset animation."); - }; - - arcball._onResetStep = function() { - info("\nlastRot: " + quat4.str(arcball._lastRot) + - "\ndeltaRot: " + quat4.str(arcball._deltaRot) + - "\ncurrentRot: " + quat4.str(arcball._currentRot) + - "\nlastTrans: " + vec3.str(arcball._lastTrans) + - "\ndeltaTrans: " + vec3.str(arcball._deltaTrans) + - "\ncurrentTrans: " + vec3.str(arcball._currentTrans) + - "\nadditionalRot: " + vec3.str(arcball._additionalRot) + - "\nadditionalTrans: " + vec3.str(arcball._additionalTrans) + - "\nzoomAmount: " + arcball._zoomAmount); - }; - - arcball._onResetFinish = function() { - ok(isApproxVec(arcball._lastRot, [0, 0, 0, 1]), - "The arcball _lastRot field wasn't reset correctly."); - ok(isApproxVec(arcball._deltaRot, [0, 0, 0, 1]), - "The arcball _deltaRot field wasn't reset correctly."); - ok(isApproxVec(arcball._currentRot, [0, 0, 0, 1]), - "The arcball _currentRot field wasn't reset correctly."); - - ok(isApproxVec(arcball._lastTrans, [0, 0, 0]), - "The arcball _lastTrans field wasn't reset correctly."); - ok(isApproxVec(arcball._deltaTrans, [0, 0, 0]), - "The arcball _deltaTrans field wasn't reset correctly."); - ok(isApproxVec(arcball._currentTrans, [0, 0, 0]), - "The arcball _currentTrans field wasn't reset correctly."); - - ok(isApproxVec(arcball._additionalRot, [0, 0, 0]), - "The arcball _additionalRot field wasn't reset correctly."); - ok(isApproxVec(arcball._additionalTrans, [0, 0, 0]), - "The arcball _additionalTrans field wasn't reset correctly."); - - ok(isApproxVec([arcball._zoomAmount], [0]), - "The arcball _zoomAmount field wasn't reset correctly."); - - executeSoon(function() { - info("Finishing arcball reset test."); - callback(); - }); - }; - - EventUtils.synthesizeKey("VK_R", { type: "keydown" }); - - }, Math.random() * 1000); // leave enough time for transforms to happen - }, Math.random() * 1000); - }, Math.random() * 1000); -} - -function cleanup() { - info("Cleaning up arcball reset test."); - - if (tiltOpened) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_arcball-reset.js b/devtools/client/tilt/test/browser_tilt_arcball-reset.js deleted file mode 100644 index b3fb769268d3..000000000000 --- a/devtools/client/tilt/test/browser_tilt_arcball-reset.js +++ /dev/null @@ -1,130 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var tiltOpened = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping part of the arcball test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping part of the arcball test because WebGL isn't supported."); - return; - } - - requestLongerTimeout(10); - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - tiltOpened = true; - - performTest(instance.presenter.canvas, - instance.controller.arcball, function() { - - info("Killing arcball reset test."); - - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function performTest(canvas, arcball, callback) { - is(document.activeElement, canvas, - "The visualizer canvas should be focused when performing this test."); - - info("Starting arcball reset test."); - - // start translating and rotating sometime at random - - window.setTimeout(function() { - info("Synthesizing key down events."); - - EventUtils.synthesizeKey("VK_W", { type: "keydown" }); - EventUtils.synthesizeKey("VK_LEFT", { type: "keydown" }); - - // wait for some arcball translations and rotations to happen - - window.setTimeout(function() { - info("Synthesizing key up events."); - - EventUtils.synthesizeKey("VK_W", { type: "keyup" }); - EventUtils.synthesizeKey("VK_LEFT", { type: "keyup" }); - - // ok, transformations finished, we can now try to reset the model view - - window.setTimeout(function() { - info("Synthesizing arcball reset key press."); - - arcball._onResetStart = function() { - info("Starting arcball reset animation."); - }; - - arcball._onResetStep = function() { - info("\nlastRot: " + quat4.str(arcball._lastRot) + - "\ndeltaRot: " + quat4.str(arcball._deltaRot) + - "\ncurrentRot: " + quat4.str(arcball._currentRot) + - "\nlastTrans: " + vec3.str(arcball._lastTrans) + - "\ndeltaTrans: " + vec3.str(arcball._deltaTrans) + - "\ncurrentTrans: " + vec3.str(arcball._currentTrans) + - "\nadditionalRot: " + vec3.str(arcball._additionalRot) + - "\nadditionalTrans: " + vec3.str(arcball._additionalTrans) + - "\nzoomAmount: " + arcball._zoomAmount); - }; - - arcball._onResetFinish = function() { - ok(isApproxVec(arcball._lastRot, [0, 0, 0, 1]), - "The arcball _lastRot field wasn't reset correctly."); - ok(isApproxVec(arcball._deltaRot, [0, 0, 0, 1]), - "The arcball _deltaRot field wasn't reset correctly."); - ok(isApproxVec(arcball._currentRot, [0, 0, 0, 1]), - "The arcball _currentRot field wasn't reset correctly."); - - ok(isApproxVec(arcball._lastTrans, [0, 0, 0]), - "The arcball _lastTrans field wasn't reset correctly."); - ok(isApproxVec(arcball._deltaTrans, [0, 0, 0]), - "The arcball _deltaTrans field wasn't reset correctly."); - ok(isApproxVec(arcball._currentTrans, [0, 0, 0]), - "The arcball _currentTrans field wasn't reset correctly."); - - ok(isApproxVec(arcball._additionalRot, [0, 0, 0]), - "The arcball _additionalRot field wasn't reset correctly."); - ok(isApproxVec(arcball._additionalTrans, [0, 0, 0]), - "The arcball _additionalTrans field wasn't reset correctly."); - - ok(isApproxVec([arcball._zoomAmount], [0]), - "The arcball _zoomAmount field wasn't reset correctly."); - - executeSoon(function() { - info("Finishing arcball reset test."); - callback(); - }); - }; - - EventUtils.synthesizeKey("VK_R", { type: "keydown" }); - - }, Math.random() * 1000); // leave enough time for transforms to happen - }, Math.random() * 1000); - }, Math.random() * 1000); -} - -function cleanup() { - info("Cleaning up arcball reset test."); - - if (tiltOpened) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_arcball.js b/devtools/client/tilt/test/browser_tilt_arcball.js deleted file mode 100644 index 3d1078e1bc3f..000000000000 --- a/devtools/client/tilt/test/browser_tilt_arcball.js +++ /dev/null @@ -1,496 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function cloneUpdate(update) { - return { - rotation: quat4.create(update.rotation), - translation: vec3.create(update.translation) - }; -} - -function isExpectedUpdate(update1, update2) { - if (update1.length !== update2.length) { - return false; - } - for (let i = 0, len = update1.length; i < len; i++) { - if (!isApproxVec(update1[i].rotation, update2[i].rotation) || - !isApproxVec(update1[i].translation, update2[i].translation)) { - info("isExpectedUpdate expected " + JSON.stringify(update1), ", got " + - JSON.stringify(update2) + " instead."); - return false; - } - } - return true; -} - -function test() { - let arcball1 = new TiltVisualizer.Arcball(window, 123, 456); - - is(arcball1.width, 123, - "The first arcball width wasn't set correctly."); - is(arcball1.height, 456, - "The first arcball height wasn't set correctly."); - is(arcball1.radius, 123, - "The first arcball radius wasn't implicitly set correctly."); - - - let arcball2 = new TiltVisualizer.Arcball(window, 987, 654); - - is(arcball2.width, 987, - "The second arcball width wasn't set correctly."); - is(arcball2.height, 654, - "The second arcball height wasn't set correctly."); - is(arcball2.radius, 654, - "The second arcball radius wasn't implicitly set correctly."); - - - let arcball3 = new TiltVisualizer.Arcball(window, 512, 512); - - let sphereVec = vec3.create(); - arcball3._pointToSphere(123, 456, 256, 512, 512, sphereVec); - - ok(isApproxVec(sphereVec, [-0.009765625, 0.390625, 0.9204980731010437]), - "The _pointToSphere() function didn't map the coordinates correctly."); - - let stack1 = []; - let expect1 = [ - { rotation: [ - -0.08877250552177429, 0.0242881178855896, - -0.04222869873046875, -0.9948599338531494], - translation: [0, 0, 0] }, - { rotation: [ - -0.13086390495300293, 0.03413732722401619, - -0.06334304809570312, -0.9887855648994446], - translation: [0, 0, 0] }, - { rotation: [ - -0.15138940513134003, 0.03854173421859741, - -0.07390022277832031, -0.9849540591239929], - translation: [0, 0, 0] }, - { rotation: [ - -0.1615273654460907, 0.040619146078825, - -0.0791788101196289, -0.9828477501869202], - translation: [0, 0, 0] }, - { rotation: [ - -0.16656573116779327, 0.04162723943591118, - -0.0818181037902832, -0.9817478656768799], - translation: [0, 0, 0] }, - { rotation: [ - -0.16907735168933868, 0.042123712599277496, - -0.08313775062561035, -0.9811863303184509], - translation: [0, 0, 0] }, - { rotation: [ - -0.17033125460147858, 0.042370058596134186, - -0.08379757404327393, -0.9809026718139648], - translation: [0, 0, 0] }, - { rotation: [ - -0.17095772922039032, 0.04249274358153343, - -0.08412748575210571, -0.9807600975036621], - translation: [0, 0, 0] }, - { rotation: [ - -0.17127084732055664, 0.04255397245287895, - -0.0842924416065216, -0.9806886315345764], - translation: [0, 0, 0] }, - { rotation: [ - -0.171427384018898, 0.042584557086229324, - -0.08437491953372955, -0.9806528687477112], - translation: [0, 0, 0] }]; - - arcball3.mouseDown(10, 10, 1); - arcball3.mouseMove(10, 100); - for (let i1 = 0; i1 < 10; i1++) { - stack1.push(cloneUpdate(arcball3.update())); - } - - ok(isExpectedUpdate(stack1, expect1), - "Mouse down & move events didn't create the expected transform. results."); - - let stack2 = []; - let expect2 = [ - { rotation: [ - -0.1684110015630722, 0.04199237748980522, - -0.0827873945236206, -0.9813361167907715], - translation: [0, 0, 0] }, - { rotation: [ - -0.16936375200748444, 0.04218007251620293, - -0.08328840136528015, -0.9811217188835144], - translation: [0, 0, 0] }, - { rotation: [ - -0.17003019154071808, 0.04231100529432297, - -0.08363909274339676, -0.9809709787368774], - translation: [0, 0, 0] }, - { rotation: [ - -0.17049652338027954, 0.042402446269989014, - -0.0838845893740654, -0.9808651208877563], - translation: [0, 0, 0] }, - { rotation: [ - -0.17082282900810242, 0.042466338723897934, - -0.08405643701553345, -0.9807908535003662], - translation: [0, 0, 0] }, - { rotation: [ - -0.17105120420455933, 0.04251104220747948, - -0.08417671173810959, -0.9807388186454773], - translation: [0, 0, 0] }, - { rotation: [ - -0.17121103405952454, 0.04254228621721268, - -0.08426092565059662, -0.9807023406028748], - translation: [0, 0, 0] }, - { rotation: [ - -0.17132291197776794, 0.042564138770103455, - -0.08431987464427948, -0.9806767106056213], - translation: [0, 0, 0] }, - { rotation: [ - -0.1714012324810028, 0.04257945716381073, - -0.08436112850904465, -0.9806588888168335], - translation: [0, 0, 0] }, - { rotation: [ - -0.17145603895187378, 0.042590171098709106, - -0.08439001441001892, -0.9806463718414307], - translation: [0, 0, 0] }]; - - arcball3.mouseUp(100, 100); - for (let i2 = 0; i2 < 10; i2++) { - stack2.push(cloneUpdate(arcball3.update())); - } - - ok(isExpectedUpdate(stack2, expect2), - "Mouse up events didn't create the expected transformation results."); - - let stack3 = []; - let expect3 = [ - { rotation: [ - -0.17149439454078674, 0.04259764403104782, - -0.08441022783517838, -0.9806375503540039], - translation: [0, 0, -1] }, - { rotation: [ - -0.17152123153209686, 0.04260288551449776, - -0.08442437648773193, -0.980631411075592], - translation: [0, 0, -1.899999976158142] }, - { rotation: [ - -0.1715400665998459, 0.04260658100247383, - -0.08443428575992584, -0.9806271195411682], - translation: [0, 0, -2.7100000381469727] }, - { rotation: [ - -0.17155319452285767, 0.04260912910103798, - -0.08444121479988098, -0.9806240797042847], - translation: [0, 0, -3.439000129699707] }, - { rotation: [ - -0.17156240344047546, 0.042610932141542435, - -0.08444607257843018, -0.9806219935417175], - translation: [0, 0, -4.095099925994873] }, - { rotation: [ - -0.1715688556432724, 0.042612191289663315, - -0.08444946259260178, -0.9806205034255981], - translation: [0, 0, -4.685589790344238] }, - { rotation: [ - -0.17157337069511414, 0.04261308163404465, - -0.0844518393278122, -0.980619490146637], - translation: [0, 0, -5.217031002044678] }, - { rotation: [ - -0.17157652974128723, 0.0426136814057827, - -0.0844535157084465, -0.9806187748908997], - translation: [0, 0, -5.6953277587890625] }, - { rotation: [ - -0.17157875001430511, 0.04261413961648941, - -0.08445467799901962, -0.9806182980537415], - translation: [0, 0, -6.125794887542725] }, - { rotation: [ - -0.17158031463623047, 0.04261442646384239, - -0.08445550501346588, -0.980617880821228], - translation: [0, 0, -6.5132155418396] }]; - - arcball3.zoom(10); - for (let i3 = 0; i3 < 10; i3++) { - stack3.push(cloneUpdate(arcball3.update())); - } - - ok(isExpectedUpdate(stack3, expect3), - "Mouse zoom events didn't create the expected transformation results."); - - let stack4 = []; - let expect4 = [ - { rotation: [ - -0.17158135771751404, 0.04261462762951851, - -0.08445606380701065, -0.9806176424026489], - translation: [0, 0, -6.861894130706787] }, - { rotation: [ - -0.1715821474790573, 0.04261479899287224, - -0.08445646613836288, -0.9806175231933594], - translation: [0, 0, -7.1757049560546875] }, - { rotation: [ - -0.1715826541185379, 0.0426148846745491, - -0.08445674180984497, -0.980617344379425], - translation: [0, 0, -7.458134651184082] }, - { rotation: [ - -0.17158304154872894, 0.04261497035622597, - -0.08445693552494049, -0.9806172847747803], - translation: [0, 0, -7.7123212814331055] }, - { rotation: [ - -0.17158329486846924, 0.042615000158548355, - -0.08445708453655243, -0.9806172251701355], - translation: [0, 0, -7.941089153289795] }, - { rotation: [ - -0.17158347368240356, 0.04261505603790283, - -0.084457166492939, -0.9806172251701355], - translation: [0, 0, -8.146980285644531] }, - { rotation: [ - -0.1715836226940155, 0.04261508584022522, - -0.08445724099874496, -0.9806171655654907], - translation: [0, 0, -8.332282066345215] }, - { rotation: [ - -0.17158368229866028, 0.04261508584022522, - -0.08445728570222855, -0.980617105960846], - translation: [0, 0, -8.499053955078125] }, - { rotation: [ - -0.17158377170562744, 0.04261511191725731, - -0.08445732295513153, -0.980617105960846], - translation: [0, 0, -8.649148941040039] }, - { rotation: [ - -0.17158380150794983, 0.04261511191725731, - -0.08445733785629272, -0.980617105960846], - translation: [0, 0, -8.784234046936035] }]; - - arcball3.keyDown(arcball3.rotateKeys.left); - arcball3.keyDown(arcball3.rotateKeys.right); - arcball3.keyDown(arcball3.rotateKeys.up); - arcball3.keyDown(arcball3.rotateKeys.down); - arcball3.keyDown(arcball3.panKeys.left); - arcball3.keyDown(arcball3.panKeys.right); - arcball3.keyDown(arcball3.panKeys.up); - arcball3.keyDown(arcball3.panKeys.down); - for (let i4 = 0; i4 < 10; i4++) { - stack4.push(cloneUpdate(arcball3.update())); - } - - ok(isExpectedUpdate(stack4, expect4), - "Key down events didn't create the expected transformation results."); - - let stack5 = []; - let expect5 = [ - { rotation: [ - -0.1715838462114334, 0.04261511191725731, - -0.08445736765861511, -0.980617105960846], - translation: [0, 0, -8.905810356140137] }, - { rotation: [ - -0.1715838462114334, 0.04261511191725731, - -0.08445736765861511, -0.980617105960846], - translation: [0, 0, -9.015229225158691] }, - { rotation: [ - -0.1715838462114334, 0.04261511191725731, - -0.08445736765861511, -0.980617105960846], - translation: [0, 0, -9.113706588745117] }, - { rotation: [ - -0.1715838611125946, 0.04261511191725731, - -0.0844573825597763, -0.9806170463562012], - translation: [0, 0, -9.202336311340332] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.282102584838867] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.35389232635498] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.418502807617188] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.476652145385742] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.528986930847168] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.576087951660156] }]; - - arcball3.keyUp(arcball3.rotateKeys.left); - arcball3.keyUp(arcball3.rotateKeys.right); - arcball3.keyUp(arcball3.rotateKeys.up); - arcball3.keyUp(arcball3.rotateKeys.down); - arcball3.keyUp(arcball3.panKeys.left); - arcball3.keyUp(arcball3.panKeys.right); - arcball3.keyUp(arcball3.panKeys.up); - arcball3.keyUp(arcball3.panKeys.down); - for (let i5 = 0; i5 < 10; i5++) { - stack5.push(cloneUpdate(arcball3.update())); - } - - ok(isExpectedUpdate(stack5, expect5), - "Key up events didn't create the expected transformation results."); - - let stack6 = []; - let expect6 = [ - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -9.618478775024414] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, -6.156630992889404] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 0.4590320587158203] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 9.913128852844238] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 21.921815872192383] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 36.22963333129883] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 52.60667037963867] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 70.84600067138672] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 90.76139831542969] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 112.18525695800781] }]; - - arcball3.keyDown(arcball3.zoomKeys["in"][0]); - arcball3.keyDown(arcball3.zoomKeys["in"][1]); - arcball3.keyDown(arcball3.zoomKeys["in"][2]); - for (let i6 = 0; i6 < 10; i6++) { - stack6.push(cloneUpdate(arcball3.update())); - } - arcball3.keyUp(arcball3.zoomKeys["in"][0]); - arcball3.keyUp(arcball3.zoomKeys["in"][1]); - arcball3.keyUp(arcball3.zoomKeys["in"][2]); - - ok(isExpectedUpdate(stack6, expect6), - "Key zoom in events didn't create the expected transformation results."); - - let stack7 = []; - let expect7 = [ - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 134.96673583984375] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 151.97006225585938] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 163.77305603027344] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 170.895751953125] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 173.80618286132812] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 172.92556762695312] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 168.6330108642578] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 161.26971435546875] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 151.1427459716797] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 138.52847290039062] }]; - - arcball3.keyDown(arcball3.zoomKeys["out"][0]); - arcball3.keyDown(arcball3.zoomKeys["out"][1]); - for (let i7 = 0; i7 < 10; i7++) { - stack7.push(cloneUpdate(arcball3.update())); - } - arcball3.keyUp(arcball3.zoomKeys["out"][0]); - arcball3.keyUp(arcball3.zoomKeys["out"][1]); - - ok(isExpectedUpdate(stack7, expect7), - "Key zoom out events didn't create the expected transformation results."); - - let stack8 = []; - let expect8 = [ - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 123.67562866210938] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 111.30806732177734] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 100.17726135253906] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 90.15953826904297] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 81.14358520507812] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 73.02922821044922] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 65.72630310058594] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 59.15367126464844] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 53.238304138183594] }, - { rotation: [ - -0.17158392071723938, 0.0426151417195797, - -0.0844573974609375, -0.980617105960846], - translation: [0, 0, 47.91447448730469] }]; - - arcball3.keyDown(arcball3.zoomKeys["unzoom"]); - for (let i8 = 0; i8 < 10; i8++) { - stack8.push(cloneUpdate(arcball3.update())); - } - arcball3.keyUp(arcball3.zoomKeys["unzoom"]); - - ok(isExpectedUpdate(stack8, expect8), - "Key zoom reset events didn't create the expected transformation results."); - - - arcball3.resize(123, 456); - is(arcball3.width, 123, - "The third arcball width wasn't updated correctly."); - is(arcball3.height, 456, - "The third arcball height wasn't updated correctly."); - is(arcball3.radius, 123, - "The third arcball radius wasn't implicitly updated correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_controller.js b/devtools/client/tilt/test/browser_tilt_controller.js deleted file mode 100644 index 282b42903478..000000000000 --- a/devtools/client/tilt/test/browser_tilt_controller.js +++ /dev/null @@ -1,138 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping controller test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping controller test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - let canvas = instance.presenter.canvas; - let prev_tran = vec3.create([0, 0, 0]); - let prev_rot = quat4.create([0, 0, 0, 1]); - - function tran() { - return instance.presenter.transforms.translation; - } - - function rot() { - return instance.presenter.transforms.rotation; - } - - function save() { - prev_tran = vec3.create(tran()); - prev_rot = quat4.create(rot()); - } - - ok(isEqualVec(tran(), prev_tran), - "At init, the translation should be zero."); - ok(isEqualVec(rot(), prev_rot), - "At init, the rotation should be zero."); - - function testEventCancel(cancellingEvent, cancellingDescription) { - let description = "testEventCancel, cancellingEvent is " + cancellingDescription + ": "; - is(document.activeElement, canvas, - description + "The visualizer canvas should be focused when performing this test."); - - EventUtils.synthesizeKey("a", { type: "keydown", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); - instance.controller._update(); - ok(!isEqualVec(rot(), prev_rot), - description + "After a rotation key is pressed, the quaternion should change."); - EventUtils.synthesizeKey("a", { type: "keyup", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); - - EventUtils.synthesizeKey("ArrowLeft", { type: "keydown", code: "ArrowLeft", keyCode: KeyboardEvent.DOM_VK_LEFT }); - instance.controller._update(); - ok(!isEqualVec(tran(), prev_tran), - description + "After a translation key is pressed, the vector should change."); - EventUtils.synthesizeKey("ArrowLeft", { type: "keyup", code: "ArrowLeft", keyCode: KeyboardEvent.DOM_VK_LEFT }); - - save(); - - - cancellingEvent(); - instance.controller._update(); - - ok(!isEqualVec(tran(), prev_tran), - description + "Even if the canvas lost focus, the vector has some inertia."); - ok(!isEqualVec(rot(), prev_rot), - description + "Even if the canvas lost focus, the quaternion has some inertia."); - - save(); - - - while (!isEqualVec(tran(), prev_tran) || - !isEqualVec(rot(), prev_rot)) { - instance.controller._update(); - save(); - } - - ok(isEqualVec(tran(), prev_tran) && isEqualVec(rot(), prev_rot), - "After focus lost, the transforms inertia eventually stops."); - } - - info("Setting typeaheadfind to true."); - - let typeaheadfindEnabled = true; - Services.prefs.setBoolPref("accessibility.typeaheadfind", typeaheadfindEnabled); - for (var i = 0; i < 2; i++) { - testEventCancel(function() { - // XXX Don't use a character which is registered as a mnemonic in the menubar. - EventUtils.synthesizeKey("A", { altKey: true, code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); - }, "Alt + A"); - testEventCancel(function() { - // XXX Don't use a character which is registered as a shortcut key. - EventUtils.synthesizeKey(";", { ctrlKey: true, code: "Semicolon", keyCode: KeyboardEvent.DOM_VK_SEMICONLON }); - }, "Ctrl + ;"); - testEventCancel(function() { - // XXX Don't use a character which is registered as a shortcut key. - EventUtils.synthesizeKey("\\", { metaKey: true, code: "Backslash", keyCode: KeyboardEvent.DOM_VK_BACK_SLASH }); - }, "Meta + \\"); - // If typeahead is enabled, Shift + T causes moving focus to the findbar because it inputs "T". - if (!typeaheadfindEnabled) { - testEventCancel(function() { - EventUtils.synthesizeKey("T", { shiftKey: true, code: "KeyT", keyCode: KeyboardEvent.DOM_VK_T }); - }, "Shift + T"); - } - - // Retry after disabling typeaheadfind. - info("Setting typeaheadfind to false."); - - typeaheadfindEnabled = false; - Services.prefs.setBoolPref("accessibility.typeaheadfind", typeaheadfindEnabled); - } - - info("Testing if loosing focus halts any stacked arcball animations."); - - testEventCancel(function() { - gBrowser.selectedBrowser.contentWindow.focus(); - }, "setting focus to the content window"); - }, - onEnd: function() - { - cleanup(); - } - }, true, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function cleanup() { - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl01.js b/devtools/client/tilt/test/browser_tilt_gl01.js deleted file mode 100644 index 7c8490bc6f20..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl01.js +++ /dev/null @@ -1,157 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl01 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - ok(renderer, - "The TiltGL.Renderer constructor should have initialized a new object."); - - ok(gl instanceof WebGLRenderingContext, - "The renderer context wasn't created correctly from the passed canvas."); - - - let clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE), - clearDepth = gl.getParameter(gl.DEPTH_CLEAR_VALUE); - - is(clearColor[0], 0, - "The default red clear color wasn't set correctly at initialization."); - is(clearColor[1], 0, - "The default green clear color wasn't set correctly at initialization."); - is(clearColor[2], 0, - "The default blue clear color wasn't set correctly at initialization."); - is(clearColor[3], 0, - "The default alpha clear color wasn't set correctly at initialization."); - is(clearDepth, 1, - "The default clear depth wasn't set correctly at initialization."); - - is(renderer.width, canvas.width, - "The renderer width wasn't set correctly from the passed canvas."); - is(renderer.height, canvas.height, - "The renderer height wasn't set correctly from the passed canvas."); - - ok(renderer.mvMatrix, - "The model view matrix wasn't initialized properly."); - ok(renderer.projMatrix, - "The model view matrix wasn't initialized properly."); - - ok(isApproxVec(renderer._fillColor, [1, 1, 1, 1]), - "The default fill color wasn't set correctly."); - ok(isApproxVec(renderer._strokeColor, [0, 0, 0, 1]), - "The default stroke color wasn't set correctly."); - is(renderer._strokeWeightValue, 1, - "The default stroke weight wasn't set correctly."); - - ok(renderer._colorShader, - "A default color shader should have been created."); - - ok(typeof renderer.Program, "function", - "At init, the renderer should have created a Program constructor."); - ok(typeof renderer.VertexBuffer, "function", - "At init, the renderer should have created a VertexBuffer constructor."); - ok(typeof renderer.IndexBuffer, "function", - "At init, the renderer should have created a IndexBuffer constructor."); - ok(typeof renderer.Texture, "function", - "At init, the renderer should have created a Texture constructor."); - - renderer.depthTest(true); - is(gl.getParameter(gl.DEPTH_TEST), true, - "The depth test wasn't enabled when requested."); - - renderer.depthTest(false); - is(gl.getParameter(gl.DEPTH_TEST), false, - "The depth test wasn't disabled when requested."); - - renderer.stencilTest(true); - is(gl.getParameter(gl.STENCIL_TEST), true, - "The stencil test wasn't enabled when requested."); - - renderer.stencilTest(false); - is(gl.getParameter(gl.STENCIL_TEST), false, - "The stencil test wasn't disabled when requested."); - - renderer.cullFace("front"); - is(gl.getParameter(gl.CULL_FACE), true, - "The cull face wasn't enabled when requested."); - is(gl.getParameter(gl.CULL_FACE_MODE), gl.FRONT, - "The cull face front mode wasn't set correctly."); - - renderer.cullFace("back"); - is(gl.getParameter(gl.CULL_FACE), true, - "The cull face wasn't enabled when requested."); - is(gl.getParameter(gl.CULL_FACE_MODE), gl.BACK, - "The cull face back mode wasn't set correctly."); - - renderer.cullFace("both"); - is(gl.getParameter(gl.CULL_FACE), true, - "The cull face wasn't enabled when requested."); - is(gl.getParameter(gl.CULL_FACE_MODE), gl.FRONT_AND_BACK, - "The cull face back mode wasn't set correctly."); - - renderer.cullFace(false); - is(gl.getParameter(gl.CULL_FACE), false, - "The cull face wasn't disabled when requested."); - - renderer.frontFace("cw"); - is(gl.getParameter(gl.FRONT_FACE), gl.CW, - "The front face cw mode wasn't set correctly."); - - renderer.frontFace("ccw"); - is(gl.getParameter(gl.FRONT_FACE), gl.CCW, - "The front face ccw mode wasn't set correctly."); - - renderer.blendMode("alpha"); - is(gl.getParameter(gl.BLEND), true, - "The blend mode wasn't enabled when requested."); - is(gl.getParameter(gl.BLEND_SRC_ALPHA), gl.SRC_ALPHA, - "The source blend func wasn't set correctly."); - is(gl.getParameter(gl.BLEND_DST_ALPHA), gl.ONE_MINUS_SRC_ALPHA, - "The destination blend func wasn't set correctly."); - - renderer.blendMode("add"); - is(gl.getParameter(gl.BLEND), true, - "The blend mode wasn't enabled when requested."); - is(gl.getParameter(gl.BLEND_SRC_ALPHA), gl.SRC_ALPHA, - "The source blend func wasn't set correctly."); - is(gl.getParameter(gl.BLEND_DST_ALPHA), gl.ONE, - "The destination blend func wasn't set correctly."); - - renderer.blendMode(false); - is(gl.getParameter(gl.CULL_FACE), false, - "The blend mode wasn't disabled when requested."); - - - is(gl.getParameter(gl.CURRENT_PROGRAM), null, - "No program should be initially set in the WebGL context."); - - renderer.useColorShader(new renderer.VertexBuffer([1, 2, 3], 3)); - - ok(gl.getParameter(gl.CURRENT_PROGRAM) instanceof WebGLProgram, - "The correct program hasn't been set in the WebGL context."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl02.js b/devtools/client/tilt/test/browser_tilt_gl02.js deleted file mode 100644 index 1d399913ce45..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl02.js +++ /dev/null @@ -1,46 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl02 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - renderer.fill([1, 0, 0, 1]); - ok(isApproxVec(renderer._fillColor, [1, 0, 0, 1]), - "The fill color wasn't set correctly."); - - renderer.stroke([0, 1, 0, 1]); - ok(isApproxVec(renderer._strokeColor, [0, 1, 0, 1]), - "The stroke color wasn't set correctly."); - - renderer.strokeWeight(2); - is(renderer._strokeWeightValue, 2, - "The stroke weight wasn't set correctly."); - is(gl.getParameter(gl.LINE_WIDTH), 2, - "The stroke weight wasn't applied correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl03.js b/devtools/client/tilt/test/browser_tilt_gl03.js deleted file mode 100644 index 916a8f7b003c..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl03.js +++ /dev/null @@ -1,69 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl03 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - renderer.defaults(); - is(gl.getParameter(gl.DEPTH_TEST), true, - "The depth test wasn't set to the correct default value."); - is(gl.getParameter(gl.STENCIL_TEST), false, - "The stencil test wasn't set to the correct default value."); - is(gl.getParameter(gl.CULL_FACE), false, - "The cull face wasn't set to the correct default value."); - is(gl.getParameter(gl.FRONT_FACE), gl.CCW, - "The front face wasn't set to the correct default value."); - is(gl.getParameter(gl.BLEND), true, - "The blend mode wasn't set to the correct default value."); - is(gl.getParameter(gl.BLEND_SRC_ALPHA), gl.SRC_ALPHA, - "The source blend func wasn't set to the correct default value."); - is(gl.getParameter(gl.BLEND_DST_ALPHA), gl.ONE_MINUS_SRC_ALPHA, - "The destination blend func wasn't set to the correct default value."); - - - ok(isApproxVec(renderer._fillColor, [1, 1, 1, 1]), - "The fill color wasn't set to the correct default value."); - ok(isApproxVec(renderer._strokeColor, [0, 0, 0, 1]), - "The stroke color wasn't set to the correct default value."); - is(renderer._strokeWeightValue, 1, - "The stroke weight wasn't set to the correct default value."); - is(gl.getParameter(gl.LINE_WIDTH), 1, - "The stroke weight wasn't applied with the correct default value."); - - - ok(isApproxVec(renderer.projMatrix, [ - 1.2071068286895752, 0, 0, 0, 0, -2.4142136573791504, 0, 0, 0, 0, - -1.0202020406723022, -1, -181.06602478027344, 181.06602478027344, - 148.14492797851562, 181.06602478027344 - ]), "The default perspective projection matrix wasn't set correctly."); - - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 - ]), "The default model view matrix wasn't set correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl04.js b/devtools/client/tilt/test/browser_tilt_gl04.js deleted file mode 100644 index 00aaba55ae6f..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl04.js +++ /dev/null @@ -1,126 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl04 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - renderer.perspective(); - ok(isApproxVec(renderer.projMatrix, [ - 1.2071068286895752, 0, 0, 0, 0, -2.4142136573791504, 0, 0, 0, 0, - -1.0202020406723022, -1, -181.06602478027344, 181.06602478027344, - 148.14492797851562, 181.06602478027344 - ]), "The default perspective proj. matrix wasn't calculated correctly."); - - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 - ]), "Changing the perpective matrix should reset the modelview by default."); - - - renderer.ortho(); - ok(isApproxVec(renderer.projMatrix, [ - 0.006666666828095913, 0, 0, 0, 0, -0.013333333656191826, 0, 0, 0, 0, -1, - 0, -1, 1, 0, 1 - ]), "The default ortho proj. matrix wasn't calculated correctly."); - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 - ]), "Changing the ortho matrix should reset the modelview by default."); - - - renderer.projection(mat4.perspective(45, 1, 0.1, 100)); - ok(isApproxVec(renderer.projMatrix, [ - 2.4142136573791504, 0, 0, 0, 0, 2.4142136573791504, 0, 0, 0, 0, - -1.0020020008087158, -1, 0, 0, -0.20020020008087158, 0 - ]), "A custom proj. matrix couldn't be set correctly."); - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 - ]), "Setting a custom proj. matrix should reset the model view by default."); - - - renderer.translate(1, 1, 1); - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1 - ]), "The translation transformation wasn't applied correctly."); - - renderer.rotate(0.5, 1, 1, 1); - ok(isApproxVec(renderer.mvMatrix, [ - 0.9183883666992188, 0.317602276802063, -0.23599065840244293, 0, - -0.23599065840244293, 0.9183883666992188, 0.317602276802063, 0, - 0.317602276802063, -0.23599065840244293, 0.9183883666992188, 0, 1, 1, 1, 1 - ]), "The rotation transformation wasn't applied correctly."); - - renderer.rotateX(0.5); - ok(isApproxVec(renderer.mvMatrix, [ - 0.9183883666992188, 0.317602276802063, -0.23599065840244293, 0, - -0.05483464524149895, 0.6928216814994812, 0.7190210819244385, 0, - 0.391862154006958, -0.6474001407623291, 0.6536949872970581, 0, 1, 1, 1, 1 - ]), "The X rotation transformation wasn't applied correctly."); - - renderer.rotateY(0.5); - ok(isApproxVec(renderer.mvMatrix, [ - 0.6180928945541382, 0.5891023874282837, -0.5204993486404419, 0, - -0.05483464524149895, 0.6928216814994812, 0.7190210819244385, 0, - 0.7841902375221252, -0.4158804416656494, 0.4605313837528229, 0, 1, 1, 1, 1 - ]), "The Y rotation transformation wasn't applied correctly."); - - renderer.rotateZ(0.5); - ok(isApproxVec(renderer.mvMatrix, [ - 0.5161384344100952, 0.8491423726081848, -0.11206408590078354, 0, - -0.3444514572620392, 0.3255774974822998, 0.8805410265922546, 0, - 0.7841902375221252, -0.4158804416656494, 0.4605313837528229, 0, 1, 1, 1, 1 - ]), "The Z rotation transformation wasn't applied correctly."); - - renderer.scale(2, 2, 2); - ok(isApproxVec(renderer.mvMatrix, [ - 1.0322768688201904, 1.6982847452163696, -0.22412817180156708, 0, - -0.6889029145240784, 0.6511549949645996, 1.7610820531845093, 0, - 1.5683804750442505, -0.8317608833312988, 0.9210627675056458, 0, 1, 1, 1, 1 - ]), "The Z rotation transformation wasn't applied correctly."); - - renderer.transform(mat4.create()); - ok(isApproxVec(renderer.mvMatrix, [ - 1.0322768688201904, 1.6982847452163696, -0.22412817180156708, 0, - -0.6889029145240784, 0.6511549949645996, 1.7610820531845093, 0, - 1.5683804750442505, -0.8317608833312988, 0.9210627675056458, 0, 1, 1, 1, 1 - ]), "The identity matrix transformation wasn't applied correctly."); - - renderer.origin(1, 1, 1); - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 - ]), "The origin wasn't reset to identity correctly."); - - renderer.translate(1, 2); - ok(isApproxVec(renderer.mvMatrix, [ - 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 0, 1 - ]), "The second translation transformation wasn't applied correctly."); - - renderer.scale(3, 4); - ok(isApproxVec(renderer.mvMatrix, [ - 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 0, 1, 2, 0, 1 - ]), "The second scale transformation wasn't applied correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl05.js b/devtools/client/tilt/test/browser_tilt_gl05.js deleted file mode 100644 index dcef21963e03..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl05.js +++ /dev/null @@ -1,42 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl05 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - let mesh = { - vertices: new renderer.VertexBuffer([1, 2, 3], 3), - indices: new renderer.IndexBuffer([1]), - }; - - ok(mesh.vertices instanceof TiltGL.VertexBuffer, - "The mesh vertices weren't saved at initialization."); - ok(mesh.indices instanceof TiltGL.IndexBuffer, - "The mesh indices weren't saved at initialization."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl06.js b/devtools/client/tilt/test/browser_tilt_gl06.js deleted file mode 100644 index 90e41a9682d7..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl06.js +++ /dev/null @@ -1,59 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl06 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - let vb = new renderer.VertexBuffer([1, 2, 3, 4, 5, 6], 3); - - ok(vb instanceof TiltGL.VertexBuffer, - "The vertex buffer object wasn't instantiated correctly."); - ok(vb._ref, - "The vertex buffer gl element wasn't created at initialization."); - ok(vb.components, - "The vertex buffer components weren't created at initialization."); - is(vb.itemSize, 3, - "The vertex buffer item size isn't set correctly."); - is(vb.numItems, 2, - "The vertex buffer number of items weren't calculated correctly."); - - - let ib = new renderer.IndexBuffer([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - - ok(ib instanceof TiltGL.IndexBuffer, - "The index buffer object wasn't instantiated correctly."); - ok(ib._ref, - "The index buffer gl element wasn't created at initialization."); - ok(ib.components, - "The index buffer components weren't created at initialization."); - is(ib.itemSize, 1, - "The index buffer item size isn't set correctly."); - is(ib.numItems, 10, - "The index buffer number of items weren't calculated correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl07.js b/devtools/client/tilt/test/browser_tilt_gl07.js deleted file mode 100644 index ab187fecd545..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl07.js +++ /dev/null @@ -1,60 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl07 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - let p = new renderer.Program({ - vs: TiltGL.ColorShader.vs, - fs: TiltGL.ColorShader.fs, - attributes: ["vertexPosition"], - uniforms: ["mvMatrix", "projMatrix", "fill"] - }); - - ok(p instanceof TiltGL.Program, - "The program object wasn't instantiated correctly."); - - ok(p._ref, - "The program WebGL object wasn't created properly."); - isnot(p._id, -1, - "The program id wasn't set properly."); - ok(p._attributes, - "The program attributes cache wasn't created properly."); - ok(p._uniforms, - "The program uniforms cache wasn't created properly."); - - is(typeof p._attributes.vertexPosition, "number", - "The vertexPosition attribute wasn't cached as it should."); - is(typeof p._uniforms.mvMatrix, "object", - "The mvMatrix uniform wasn't cached as it should."); - is(typeof p._uniforms.projMatrix, "object", - "The projMatrix uniform wasn't cached as it should."); - is(typeof p._uniforms.fill, "object", - "The fill uniform wasn't cached as it should."); -} diff --git a/devtools/client/tilt/test/browser_tilt_gl08.js b/devtools/client/tilt/test/browser_tilt_gl08.js deleted file mode 100644 index c074989a8b25..000000000000 --- a/devtools/client/tilt/test/browser_tilt_gl08.js +++ /dev/null @@ -1,51 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var isWebGLAvailable; - -function onWebGLFail() { - isWebGLAvailable = false; -} - -function onWebGLSuccess() { - isWebGLAvailable = true; -} - -function test() { - if (!isWebGLSupported()) { - aborting(); - info("Skipping tilt_gl08 because WebGL isn't supported on this hardware."); - return; - } - - let canvas = createCanvas(); - - let renderer = new TiltGL.Renderer(canvas, onWebGLFail, onWebGLSuccess); - let gl = renderer.context; - - if (!isWebGLAvailable) { - aborting(); - return; - } - - - let t = new renderer.Texture({ - source: canvas, - format: "RGB" - }); - - ok(t instanceof TiltGL.Texture, - "The texture object wasn't instantiated correctly."); - - ok(t._ref, - "The texture WebGL object wasn't created properly."); - isnot(t._id, -1, - "The texture id wasn't set properly."); - isnot(t.width, -1, - "The texture width wasn't set properly."); - isnot(t.height, -1, - "The texture height wasn't set properly."); - ok(t.loaded, - "The texture loaded flag wasn't set to true as it should."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math01.js b/devtools/client/tilt/test/browser_tilt_math01.js deleted file mode 100644 index da9e232859d1..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math01.js +++ /dev/null @@ -1,59 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - ok(isApprox(TiltMath.radians(30), 0.523598775), - "The radians() function didn't calculate the value correctly."); - - ok(isApprox(TiltMath.degrees(0.5), 28.64788975), - "The degrees() function didn't calculate the value correctly."); - - ok(isApprox(TiltMath.map(0.5, 0, 1, 0, 100), 50), - "The map() function didn't calculate the value correctly."); - - is(TiltMath.isPowerOfTwo(32), true, - "The isPowerOfTwo() function didn't return the expected value."); - - is(TiltMath.isPowerOfTwo(33), false, - "The isPowerOfTwo() function didn't return the expected value."); - - ok(isApprox(TiltMath.nextPowerOfTwo(31), 32), - "The nextPowerOfTwo() function didn't calculate the 1st value correctly."); - - ok(isApprox(TiltMath.nextPowerOfTwo(32), 32), - "The nextPowerOfTwo() function didn't calculate the 2nd value correctly."); - - ok(isApprox(TiltMath.nextPowerOfTwo(33), 64), - "The nextPowerOfTwo() function didn't calculate the 3rd value correctly."); - - ok(isApprox(TiltMath.clamp(5, 1, 3), 3), - "The clamp() function didn't calculate the 1st value correctly."); - - ok(isApprox(TiltMath.clamp(5, 3, 1), 3), - "The clamp() function didn't calculate the 2nd value correctly."); - - ok(isApprox(TiltMath.saturate(5), 1), - "The saturate() function didn't calculate the 1st value correctly."); - - ok(isApprox(TiltMath.saturate(-5), 0), - "The saturate() function didn't calculate the 2nd value correctly."); - - ok(isApproxVec(TiltMath.hex2rgba("#f00"), [1, 0, 0, 1]), - "The hex2rgba() function didn't calculate the 1st rgba values correctly."); - - ok(isApproxVec(TiltMath.hex2rgba("#f008"), [1, 0, 0, 0.53]), - "The hex2rgba() function didn't calculate the 2nd rgba values correctly."); - - ok(isApproxVec(TiltMath.hex2rgba("#ff0000"), [1, 0, 0, 1]), - "The hex2rgba() function didn't calculate the 3rd rgba values correctly."); - - ok(isApproxVec(TiltMath.hex2rgba("#ff0000aa"), [1, 0, 0, 0.66]), - "The hex2rgba() function didn't calculate the 4th rgba values correctly."); - - ok(isApproxVec(TiltMath.hex2rgba("rgba(255, 0, 0, 0.5)"), [1, 0, 0, 0.5]), - "The hex2rgba() function didn't calculate the 5th rgba values correctly."); - - ok(isApproxVec(TiltMath.hex2rgba("rgb(255, 0, 0)"), [1, 0, 0, 1]), - "The hex2rgba() function didn't calculate the 6th rgba values correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math02.js b/devtools/client/tilt/test/browser_tilt_math02.js deleted file mode 100644 index dae2708c40a3..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math02.js +++ /dev/null @@ -1,104 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let v1 = vec3.create(); - - ok(v1, "Should have created a vector with vec3.create()."); - is(v1.length, 3, "A vec3 should have 3 elements."); - - ok(isApproxVec(v1, [0, 0, 0]), - "When created, a vec3 should have the values default to 0."); - - vec3.set([1, 2, 3], v1); - ok(isApproxVec(v1, [1, 2, 3]), - "The vec3.set() function didn't set the values correctly."); - - vec3.zero(v1); - ok(isApproxVec(v1, [0, 0, 0]), - "The vec3.zero() function didn't set the values correctly."); - - let v2 = vec3.create([4, 5, 6]); - ok(isApproxVec(v2, [4, 5, 6]), - "When cloning arrays, a vec3 should have the values copied."); - - let v3 = vec3.create(v2); - ok(isApproxVec(v3, [4, 5, 6]), - "When cloning vectors, a vec3 should have the values copied."); - - vec3.add(v2, v3); - ok(isApproxVec(v2, [8, 10, 12]), - "The vec3.add() function didn't set the x value correctly."); - - vec3.subtract(v2, v3); - ok(isApproxVec(v2, [4, 5, 6]), - "The vec3.subtract() function didn't set the values correctly."); - - vec3.negate(v2); - ok(isApproxVec(v2, [-4, -5, -6]), - "The vec3.negate() function didn't set the values correctly."); - - vec3.scale(v2, -2); - ok(isApproxVec(v2, [8, 10, 12]), - "The vec3.scale() function didn't set the values correctly."); - - vec3.normalize(v1); - ok(isApproxVec(v1, [0, 0, 0]), - "Normalizing a vector with zero length should return [0, 0, 0]."); - - vec3.normalize(v2); - ok(isApproxVec(v2, [ - 0.4558423161506653, 0.5698028802871704, 0.6837634444236755 - ]), "The vec3.normalize() function didn't set the values correctly."); - - vec3.cross(v2, v3); - ok(isApproxVec(v2, [ - 5.960464477539063e-8, -1.1920928955078125e-7, 5.960464477539063e-8 - ]), "The vec3.cross() function didn't set the values correctly."); - - vec3.dot(v2, v3); - ok(isApproxVec(v2, [ - 5.960464477539063e-8, -1.1920928955078125e-7, 5.960464477539063e-8 - ]), "The vec3.dot() function didn't set the values correctly."); - - ok(isApproxVec([vec3.length(v2)], [1.4600096599955427e-7]), - "The vec3.length() function didn't calculate the value correctly."); - - vec3.direction(v2, v3); - ok(isApproxVec(v2, [ - -0.4558422863483429, -0.5698028802871704, -0.6837634444236755 - ]), "The vec3.direction() function didn't set the values correctly."); - - vec3.lerp(v2, v3, 0.5); - ok(isApproxVec(v2, [ - 1.7720788717269897, 2.2150986194610596, 2.65811824798584 - ]), "The vec3.lerp() function didn't set the values correctly."); - - - vec3.project([100, 100, 10], [0, 0, 100, 100], - mat4.create(), mat4.perspective(45, 1, 0.1, 100), v1); - ok(isApproxVec(v1, [-1157.10693359375, 1257.10693359375, 0]), - "The vec3.project() function didn't set the values correctly."); - - vec3.unproject([100, 100, 1], [0, 0, 100, 100], - mat4.create(), mat4.perspective(45, 1, 0.1, 100), v1); - ok(isApproxVec(v1, [ - 41.420406341552734, -41.420406341552734, -99.99771118164062 - ]), "The vec3.project() function didn't set the values correctly."); - - - let ray = vec3.createRay([10, 10, 0], [100, 100, 1], [0, 0, 100, 100], - mat4.create(), mat4.perspective(45, 1, 0.1, 100)); - - ok(isApproxVec(ray.origin, [ - -0.03313708305358887, 0.03313708305358887, -0.1000000014901161 - ]), "The vec3.createRay() function didn't create the position correctly."); - ok(isApproxVec(ray.direction, [ - 0.35788586614428364, -0.35788586614428364, -0.862458934459091 - ]), "The vec3.createRay() function didn't create the direction correctly."); - - - is(vec3.str([0, 0, 0]), "[0, 0, 0]", - "The vec3.str() function didn't work properly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math03.js b/devtools/client/tilt/test/browser_tilt_math03.js deleted file mode 100644 index 9a039ae7749b..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math03.js +++ /dev/null @@ -1,33 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let m1 = mat3.create(); - - ok(m1, "Should have created a matrix with mat3.create()."); - is(m1.length, 9, "A mat3 should have 9 elements."); - - ok(isApproxVec(m1, [1, 0, 0, 0, 1, 0, 0, 0, 1]), - "When created, a mat3 should have the values default to identity."); - - mat3.set([1, 2, 3, 4, 5, 6, 7, 8, 9], m1); - ok(isApproxVec(m1, [1, 2, 3, 4, 5, 6, 7, 8, 9]), - "The mat3.set() function didn't set the values correctly."); - - mat3.transpose(m1); - ok(isApproxVec(m1, [1, 4, 7, 2, 5, 8, 3, 6, 9]), - "The mat3.transpose() function didn't set the values correctly."); - - mat3.identity(m1); - ok(isApproxVec(m1, [1, 0, 0, 0, 1, 0, 0, 0, 1]), - "The mat3.identity() function didn't set the values correctly."); - - let m2 = mat3.toMat4(m1); - ok(isApproxVec(m2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), - "The mat3.toMat4() function didn't set the values correctly."); - - - is(mat3.str([1, 2, 3, 4, 5, 6, 7, 8, 9]), "[1, 2, 3, 4, 5, 6, 7, 8, 9]", - "The mat3.str() function didn't work properly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math04.js b/devtools/client/tilt/test/browser_tilt_math04.js deleted file mode 100644 index 587dc45fd68f..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math04.js +++ /dev/null @@ -1,49 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let m1 = mat4.create(); - - ok(m1, "Should have created a matrix with mat4.create()."); - is(m1.length, 16, "A mat4 should have 16 elements."); - - ok(isApproxVec(m1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), - "When created, a mat4 should have the values default to identity."); - - mat4.set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1); - ok(isApproxVec(m1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), - "The mat4.set() function didn't set the values correctly."); - - mat4.transpose(m1); - ok(isApproxVec(m1, [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16]), - "The mat4.transpose() function didn't set the values correctly."); - - mat4.identity(m1); - ok(isApproxVec(m1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), - "The mat4.identity() function didn't set the values correctly."); - - ok(isApprox(mat4.determinant(m1), 1), - "The mat4.determinant() function didn't calculate the value correctly."); - - let m2 = mat4.inverse([1, 3, 1, 1, 1, 1, 2, 1, 2, 3, 4, 1, 1, 1, 1, 1]); - ok(isApproxVec(m2, [ - -1, -3, 1, 3, 0.5, 0, 0, -0.5, 0, 1, 0, -1, 0.5, 2, -1, -0.5 - ]), "The mat4.inverse() function didn't calculate the values correctly."); - - let m3 = mat4.toRotationMat([ - 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16]); - ok(isApproxVec(m3, [ - 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 0, 0, 0, 1 - ]), "The mat4.toRotationMat() func. didn't calculate the values correctly."); - - let m4 = mat4.toMat3([ - 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16]); - ok(isApproxVec(m4, [1, 5, 9, 2, 6, 10, 3, 7, 11]), - "The mat4.toMat3() function didn't set the values correctly."); - - let m5 = mat4.toInverseMat3([ - 1, 3, 1, 1, 1, 1, 2, 1, 2, 3, 4, 1, 1, 1, 1, 1]); - ok(isApproxVec(m5, [2, 9, -5, 0, -2, 1, -1, -3, 2]), - "The mat4.toInverseMat3() function didn't set the values correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math05.js b/devtools/client/tilt/test/browser_tilt_math05.js deleted file mode 100644 index d39695f55e1b..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math05.js +++ /dev/null @@ -1,101 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let m1 = mat4.create([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]); - - let m2 = mat4.create([ - 0, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16]); - - mat4.multiply(m1, m2); - ok(isApproxVec(m1, [ - 275, 302, 329, 356, 304, 336, 368, 400, - 332, 368, 404, 440, 360, 400, 440, 480 - ]), "The mat4.multiply() function didn't set the values correctly."); - - let v1 = mat4.multiplyVec3(m1, [1, 2, 3]); - ok(isApproxVec(v1, [2239, 2478, 2717]), - "The mat4.multiplyVec3() function didn't set the values correctly."); - - let v2 = mat4.multiplyVec4(m1, [1, 2, 3, 0]); - ok(isApproxVec(v2, [1879, 2078, 2277, 2476]), - "The mat4.multiplyVec4() function didn't set the values correctly."); - - mat4.translate(m1, [1, 2, 3]); - ok(isApproxVec(m1, [ - 275, 302, 329, 356, 304, 336, 368, 400, - 332, 368, 404, 440, 2239, 2478, 2717, 2956 - ]), "The mat4.translate() function didn't set the values correctly."); - - mat4.scale(m1, [1, 2, 3]); - ok(isApproxVec(m1, [ - 275, 302, 329, 356, 608, 672, 736, 800, - 996, 1104, 1212, 1320, 2239, 2478, 2717, 2956 - ]), "The mat4.scale() function didn't set the values correctly."); - - mat4.rotate(m1, 0.5, [1, 1, 1]); - ok(isApproxVec(m1, [ - 210.6123046875, 230.2483367919922, 249.88438415527344, 269.5204162597656, - 809.8145751953125, 896.520751953125, 983.2268676757812, - 1069.9329833984375, 858.5731201171875, 951.23095703125, - 1043.8887939453125, 1136.5465087890625, 2239, 2478, 2717, 2956 - ]), "The mat4.rotate() function didn't set the values correctly."); - - mat4.rotateX(m1, 0.5); - ok(isApproxVec(m1, [ - 210.6123046875, 230.2483367919922, 249.88438415527344, 269.5204162597656, - 1122.301025390625, 1242.8154296875, 1363.3297119140625, - 1483.843994140625, 365.2230224609375, 404.96875, 444.71453857421875, - 484.460205078125, 2239, 2478, 2717, 2956 - ]), "The mat4.rotateX() function didn't set the values correctly."); - - mat4.rotateY(m1, 0.5); - ok(isApproxVec(m1, [ - 9.732441902160645, 7.909564018249512, 6.086670875549316, - 4.263822555541992, 1122.301025390625, 1242.8154296875, 1363.3297119140625, - 1483.843994140625, 421.48626708984375, 465.78045654296875, - 510.0746765136719, 554.3687744140625, 2239, 2478, 2717, 2956 - ]), "The mat4.rotateY() function didn't set the values correctly."); - - mat4.rotateZ(m1, 0.5); - ok(isApproxVec(m1, [ - 546.6007690429688, 602.7787475585938, 658.9566650390625, 715.1345825195312, - 980.245849609375, 1086.881103515625, 1193.5162353515625, - 1300.1514892578125, 421.48626708984375, 465.78045654296875, - 510.0746765136719, 554.3687744140625, 2239, 2478, 2717, 2956 - ]), "The mat4.rotateZ() function didn't set the values correctly."); - - - let m3 = mat4.frustum(0, 100, 200, 0, 0.1, 100); - ok(isApproxVec(m3, [ - 0.0020000000949949026, 0, 0, 0, 0, -0.0010000000474974513, 0, 0, 1, -1, - -1.0020020008087158, -1, 0, 0, -0.20020020008087158, 0 - ]), "The mat4.frustum() function didn't compute the values correctly."); - - let m4 = mat4.perspective(45, 1.6, 0.1, 100); - ok(isApproxVec(m4, [1.5088834762573242, 0, 0, 0, 0, 2.4142136573791504, 0, - 0, 0, 0, -1.0020020008087158, -1, 0, 0, -0.20020020008087158, 0 - ]), "The mat4.frustum() function didn't compute the values correctly."); - - let m5 = mat4.ortho(0, 100, 200, 0, -1, 1); - ok(isApproxVec(m5, [ - 0.019999999552965164, 0, 0, 0, 0, -0.009999999776482582, 0, 0, - 0, 0, -1, 0, -1, 1, 0, 1 - ]), "The mat4.ortho() function didn't compute the values correctly."); - - let m6 = mat4.lookAt([1, 2, 3], [4, 5, 6], [0, 1, 0]); - ok(isApproxVec(m6, [ - -0.7071067690849304, -0.40824830532073975, -0.5773502588272095, 0, 0, - 0.8164966106414795, -0.5773502588272095, 0, 0.7071067690849304, - -0.40824830532073975, -0.5773502588272095, 0, -1.4142135381698608, 0, - 3.464101552963257, 1 - ]), "The mat4.lookAt() function didn't compute the values correctly."); - - - is(mat4.str([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), - "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]", - "The mat4.str() function didn't work properly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math06.js b/devtools/client/tilt/test/browser_tilt_math06.js deleted file mode 100644 index 2ed331eaa101..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math06.js +++ /dev/null @@ -1,42 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let q1 = quat4.create(); - - ok(q1, "Should have created a quaternion with quat4.create()."); - is(q1.length, 4, "A quat4 should have 4 elements."); - - ok(isApproxVec(q1, [0, 0, 0, 1]), - "When created, a vec3 should have the values default to identity."); - - quat4.set([1, 2, 3, 4], q1); - ok(isApproxVec(q1, [1, 2, 3, 4]), - "The quat4.set() function didn't set the values correctly."); - - quat4.identity(q1); - ok(isApproxVec(q1, [0, 0, 0, 1]), - "The quat4.identity() function didn't set the values correctly."); - - quat4.set([5, 6, 7, 8], q1); - ok(isApproxVec(q1, [5, 6, 7, 8]), - "The quat4.set() function didn't set the values correctly."); - - quat4.calculateW(q1); - ok(isApproxVec(q1, [5, 6, 7, -10.440306663513184]), - "The quat4.calculateW() function didn't compute the values correctly."); - - quat4.inverse(q1); - ok(isApproxVec(q1, [-5, -6, -7, -10.440306663513184]), - "The quat4.inverse() function didn't compute the values correctly."); - - quat4.normalize(q1); - ok(isApproxVec(q1, [ - -0.33786869049072266, -0.40544241666793823, - -0.4730161726474762, -0.7054905295372009 - ]), "The quat4.normalize() function didn't compute the values correctly."); - - ok(isApprox(quat4.length(q1), 1), - "The mat4.length() function didn't calculate the value correctly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_math07.js b/devtools/client/tilt/test/browser_tilt_math07.js deleted file mode 100644 index 309d3763dd09..000000000000 --- a/devtools/client/tilt/test/browser_tilt_math07.js +++ /dev/null @@ -1,49 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let q1 = quat4.create([1, 2, 3, 4]); - let q2 = quat4.create([5, 6, 7, 8]); - - quat4.multiply(q1, q2); - ok(isApproxVec(q1, [24, 48, 48, -6]), - "The quat4.multiply() function didn't set the values correctly."); - - let v1 = quat4.multiplyVec3(q1, [9, 9, 9]); - ok(isApproxVec(v1, [5508, 54756, 59940]), - "The quat4.multiplyVec3() function didn't set the values correctly."); - - let m1 = quat4.toMat3(q1); - ok(isApproxVec(m1, [ - -9215, 2880, 1728, 1728, -5759, 4896, 2880, 4320, -5759 - ]), "The quat4.toMat3() function didn't set the values correctly."); - - let m2 = quat4.toMat4(q1); - ok(isApproxVec(m2, [ - -9215, 2880, 1728, 0, 1728, -5759, 4896, 0, - 2880, 4320, -5759, 0, 0, 0, 0, 1 - ]), "The quat4.toMat4() function didn't set the values correctly."); - - quat4.calculateW(q1); - quat4.calculateW(q2); - quat4.slerp(q1, q2, 0.5); - ok(isApproxVec(q1, [24, 48, 48, -71.99305725097656]), - "The quat4.slerp() function didn't set the values correctly."); - - let q3 = quat4.fromAxis([1, 1, 1], 0.5); - ok(isApproxVec(q3, [ - 0.24740396440029144, 0.24740396440029144, 0.24740396440029144, - 0.9689124226570129 - ]), "The quat4.fromAxis() function didn't compute the values correctly."); - - let q4 = quat4.fromEuler(0.5, 0.75, 1.25); - ok(isApproxVec(q4, [ - 0.15310347080230713, 0.39433568716049194, - 0.4540249705314636, 0.7841683626174927 - ]), "The quat4.fromEuler() function didn't compute the values correctly."); - - - is(quat4.str([1, 2, 3, 4]), "[1, 2, 3, 4]", - "The quat4.str() function didn't work properly."); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking.js b/devtools/client/tilt/test/browser_tilt_picking.js deleted file mode 100644 index e024fbaeec2e..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking.js +++ /dev/null @@ -1,56 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var pickDone = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping picking test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping picking test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - let presenter = instance.presenter; - let canvas = presenter.canvas; - - presenter._onSetupMesh = function() { - let p = getPickablePoint(presenter); - - presenter.pickNode(p[0], p[1], { - onpick: function(data) - { - ok(data.index > 0, - "Simply picking a node didn't work properly."); - - pickDone = true; - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - } - }); - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function cleanup() { - if (pickDone) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_delete.js b/devtools/client/tilt/test/browser_tilt_picking_delete.js deleted file mode 100644 index edd527c1d83c..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_delete.js +++ /dev/null @@ -1,78 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var nodeDeleted = false; -var presenter; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping picking delete test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping picking delete test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - presenter = instance.presenter; - Services.obs.addObserver(whenNodeRemoved, NODE_REMOVED, false); - - presenter._onSetupMesh = function() { - let p = getPickablePoint(presenter); - - presenter.highlightNodeAt(p[0], p[1], { - onpick: function() - { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - - nodeDeleted = true; - presenter.deleteNode(); - } - }); - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function whenNodeRemoved() { - ok(presenter._currentSelection > 0, - "Deleting a node shouldn't change the current selection."); - ok(presenter._highlight.disabled, - "After deleting a node, it shouldn't be highlighted."); - - let nodeIndex = presenter._currentSelection; - let vertices = presenter._meshStacks[0].vertices.components; - - for (let i = 0, k = 36 * nodeIndex; i < 36; i++) { - is(vertices[i + k], 0, - "The stack vertices weren't degenerated properly."); - } - - executeSoon(function() { - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - if (nodeDeleted) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_highlight01-offs.js b/devtools/client/tilt/test/browser_tilt_picking_highlight01-offs.js deleted file mode 100644 index 9be0cf8b1552..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_highlight01-offs.js +++ /dev/null @@ -1,77 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var nodeHighlighted = false; -var presenter; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping highlight test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping highlight test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - presenter = instance.presenter; - Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false); - - presenter._onInitializationFinished = function() { - let contentDocument = presenter.contentWindow.document; - let div = contentDocument.getElementById("far-far-away"); - - nodeHighlighted = true; - presenter.highlightNode(div, "moveIntoView"); - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function whenHighlighting() { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - ok(presenter.controller.arcball._resetInProgress, - "Highlighting a node that's not already visible should trigger a reset!"); - - executeSoon(function() { - Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING); - Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false); - presenter.highlightNode(null); - }); -} - -function whenUnhighlighting() { - ok(presenter._currentSelection < 0, - "Unhighlighting a should remove the current selection."); - ok(presenter._highlight.disabled, - "After unhighlighting a node, it shouldn't be highlighted anymore. D'oh."); - - executeSoon(function() { - Services.obs.removeObserver(whenUnhighlighting, UNHIGHLIGHTING); - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - if (nodeHighlighted) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_highlight01.js b/devtools/client/tilt/test/browser_tilt_picking_highlight01.js deleted file mode 100644 index 64d1e4ca023d..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_highlight01.js +++ /dev/null @@ -1,77 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var nodeHighlighted = false; -var presenter; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping highlight test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping highlight test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - presenter = instance.presenter; - Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false); - - presenter._onInitializationFinished = function() { - let contentDocument = presenter.contentWindow.document; - let div = contentDocument.getElementById("first-law"); - - nodeHighlighted = true; - presenter.highlightNode(div, "moveIntoView"); - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function whenHighlighting() { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - ok(!presenter.controller.arcball._resetInProgress, - "Highlighting a node that's already visible shouldn't trigger a reset."); - - executeSoon(function() { - Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING); - Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false); - presenter.highlightNode(null); - }); -} - -function whenUnhighlighting() { - ok(presenter._currentSelection < 0, - "Unhighlighting a should remove the current selection."); - ok(presenter._highlight.disabled, - "After unhighlighting a node, it shouldn't be highlighted anymore. D'oh."); - - executeSoon(function() { - Services.obs.removeObserver(whenUnhighlighting, UNHIGHLIGHTING); - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - if (nodeHighlighted) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_highlight02.js b/devtools/client/tilt/test/browser_tilt_picking_highlight02.js deleted file mode 100644 index 822f93319022..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_highlight02.js +++ /dev/null @@ -1,72 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var nodeHighlighted = false; -var presenter; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping highlight test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping highlight test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - presenter = instance.presenter; - Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false); - - presenter._onInitializationFinished = function() { - nodeHighlighted = true; - presenter.highlightNodeAt.apply(this, getPickablePoint(presenter)); - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function whenHighlighting() { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - - executeSoon(function() { - Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING); - Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false); - presenter.highlightNode(null); - }); -} - -function whenUnhighlighting() { - ok(presenter._currentSelection < 0, - "Unhighlighting a should remove the current selection."); - ok(presenter._highlight.disabled, - "After unhighlighting a node, it shouldn't be highlighted anymore. D'oh."); - - executeSoon(function() { - Services.obs.removeObserver(whenUnhighlighting, UNHIGHLIGHTING); - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - if (nodeHighlighted) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_highlight03.js b/devtools/client/tilt/test/browser_tilt_picking_highlight03.js deleted file mode 100644 index e77b46e4f935..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_highlight03.js +++ /dev/null @@ -1,72 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var nodeHighlighted = false; -var presenter; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping highlight test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping highlight test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - presenter = instance.presenter; - Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false); - - presenter._onInitializationFinished = function() { - nodeHighlighted = true; - presenter.highlightNodeFor(3); // 1 = html, 2 = body, 3 = first div - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function whenHighlighting() { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - - executeSoon(function() { - Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING); - Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false); - presenter.highlightNodeFor(-1); - }); -} - -function whenUnhighlighting() { - ok(presenter._currentSelection < 0, - "Unhighlighting a should remove the current selection."); - ok(presenter._highlight.disabled, - "After unhighlighting a node, it shouldn't be highlighted anymore. D'oh."); - - executeSoon(function() { - Services.obs.removeObserver(whenUnhighlighting, UNHIGHLIGHTING); - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - if (nodeHighlighted) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_inspector.js b/devtools/client/tilt/test/browser_tilt_picking_inspector.js deleted file mode 100644 index 062330fc7447..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_inspector.js +++ /dev/null @@ -1,76 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -Components.utils.import("resource://gre/modules/Task.jsm"); -var promise = require("promise"); - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping highlight test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping highlight test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - let {TargetFactory} = require("devtools/client/framework/target"); - let target = TargetFactory.forTab(gBrowser.selectedTab); - - gDevTools.showToolbox(target, "inspector") - .then(Task.async(onToolbox)); - }); -} - -function* onToolbox(toolbox) { - let contentDocument = toolbox.target.tab.linkedBrowser.contentDocument; - let div = contentDocument.getElementById("first-law"); - let inspector = toolbox.getPanel("inspector"); - - let onInspectorUpdated = inspector.once("inspector-updated"); - inspector.selection.setNode(div); - yield onInspectorUpdated; - - let deferred = promise.defer(); - onInspectorUpdated = inspector.once("inspector-updated"); - createTilt({ - onTiltOpen: function(instance) - { - deferred.resolve(instance.presenter); - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - let presenter = yield deferred.promise; - yield onInspectorUpdated; - - whenOpen(presenter); -} - -function whenOpen(presenter) { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - ok(!presenter.controller.arcball._resetInProgress, - "Highlighting a node that's already visible shouldn't trigger a reset."); - - executeSoon(function() { - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - Services.obs.removeObserver(cleanup, DESTROYED); - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_picking_miv.js b/devtools/client/tilt/test/browser_tilt_picking_miv.js deleted file mode 100644 index acfcc27e8407..000000000000 --- a/devtools/client/tilt/test/browser_tilt_picking_miv.js +++ /dev/null @@ -1,78 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var nodeHighlighted = false; -var presenter; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping highlight test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping highlight test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - createTab(function() { - createTilt({ - onTiltOpen: function(instance) - { - presenter = instance.presenter; - Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false); - - presenter._onInitializationFinished = function() { - let contentDocument = presenter.contentWindow.document; - let div = contentDocument.getElementById("far-far-away"); - - nodeHighlighted = true; - presenter.highlightNode(div); - }; - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function whenHighlighting() { - ok(presenter._currentSelection > 0, - "Highlighting a node didn't work properly."); - ok(!presenter._highlight.disabled, - "After highlighting a node, it should be highlighted. D'oh."); - ok(!presenter.controller.arcball._resetInProgress, - "Highlighting a node that's not already visible shouldn't trigger a reset " + - "without this being explicitly requested!"); - - EventUtils.sendKey("F"); - executeSoon(whenBringingIntoView); -} - -function whenBringingIntoView() { - ok(presenter._currentSelection > 0, - "The node should still be selected."); - ok(!presenter._highlight.disabled, - "The node should still be highlighted"); - ok(presenter.controller.arcball._resetInProgress, - "Highlighting a node that's not already visible should trigger a reset " + - "when this is being explicitly requested!"); - - executeSoon(function() { - Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING); - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); -} - -function cleanup() { - if (nodeHighlighted) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils01.js b/devtools/client/tilt/test/browser_tilt_utils01.js deleted file mode 100644 index 7beb6a3a27f3..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils01.js +++ /dev/null @@ -1,69 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let prefs = TiltUtils.Preferences; - ok(prefs, "The TiltUtils.Preferences wasn't found."); - - prefs.create("test-pref-bool", "boolean", true); - prefs.create("test-pref-int", "integer", 42); - prefs.create("test-pref-string", "string", "hello world!"); - - is(prefs.get("test-pref-bool", "boolean"), true, - "The boolean test preference wasn't initially set correctly."); - is(prefs.get("test-pref-int", "integer"), 42, - "The integer test preference wasn't initially set correctly."); - is(prefs.get("test-pref-string", "string"), "hello world!", - "The string test preference wasn't initially set correctly."); - - - prefs.set("test-pref-bool", "boolean", false); - prefs.set("test-pref-int", "integer", 24); - prefs.set("test-pref-string", "string", "!dlrow olleh"); - - is(prefs.get("test-pref-bool", "boolean"), false, - "The boolean test preference wasn't changed correctly."); - is(prefs.get("test-pref-int", "integer"), 24, - "The integer test preference wasn't changed correctly."); - is(prefs.get("test-pref-string", "string"), "!dlrow olleh", - "The string test preference wasn't changed correctly."); - - - is(typeof prefs.get("unknown-pref", "boolean"), "undefined", - "Inexisted boolean prefs should be handled as undefined."); - is(typeof prefs.get("unknown-pref", "integer"), "undefined", - "Inexisted integer prefs should be handled as undefined."); - is(typeof prefs.get("unknown-pref", "string"), "undefined", - "Inexisted string prefs should be handled as undefined."); - - - is(prefs.get("test-pref-bool", "integer"), null, - "The get() boolean function didn't handle incorrect types as it should."); - is(prefs.get("test-pref-bool", "string"), null, - "The get() boolean function didn't handle incorrect types as it should."); - is(prefs.get("test-pref-int", "boolean"), null, - "The get() integer function didn't handle incorrect types as it should."); - is(prefs.get("test-pref-int", "string"), null, - "The get() integer function didn't handle incorrect types as it should."); - is(prefs.get("test-pref-string", "boolean"), null, - "The get() string function didn't handle incorrect types as it should."); - is(prefs.get("test-pref-string", "integer"), null, - "The get() string function didn't handle incorrect types as it should."); - - - is(typeof prefs.get(), "undefined", - "The get() function should not work if not enough params are passed."); - is(typeof prefs.set(), "undefined", - "The set() function should not work if not enough params are passed."); - is(typeof prefs.create(), "undefined", - "The create() function should not work if not enough params are passed."); - - - is(prefs.get("test-pref-wrong-type", "wrong-type", 1), null, - "The get() function should expect only correct pref types."); - is(prefs.set("test-pref-wrong-type", "wrong-type", 1), false, - "The set() function should expect only correct pref types."); - is(prefs.create("test-pref-wrong-type", "wrong-type", 1), false, - "The create() function should expect only correct pref types."); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils02.js b/devtools/client/tilt/test/browser_tilt_utils02.js deleted file mode 100644 index b9c710a8a70a..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils02.js +++ /dev/null @@ -1,21 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let l10 = TiltUtils.L10n; - ok(l10, "The TiltUtils.L10n wasn't found."); - - - ok(l10.stringBundle, - "The necessary string bundle wasn't found."); - is(l10.get(), null, - "The get() function shouldn't work if no params are passed."); - is(l10.format(), null, - "The format() function shouldn't work if no params are passed."); - - is(typeof l10.get("initWebGL.error"), "string", - "No valid string was returned from a correct name in the bundle."); - is(typeof l10.format("linkProgram.error", ["error"]), "string", - "No valid formatted string was returned from a name in the bundle."); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils03.js b/devtools/client/tilt/test/browser_tilt_utils03.js deleted file mode 100644 index 61d256fe171a..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils03.js +++ /dev/null @@ -1,18 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let dom = TiltUtils.DOM; - - is(dom.parentNode, null, - "The parent node should not be initially set."); - - dom.parentNode = {}; - ok(dom.parentNode, - "The parent node should now be set."); - - TiltUtils.clearCache(); - is(dom.parentNode, null, - "The parent node should not be set after clearing the cache."); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils04.js b/devtools/client/tilt/test/browser_tilt_utils04.js deleted file mode 100644 index 8574c266ec28..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils04.js +++ /dev/null @@ -1,54 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - let dom = TiltUtils.DOM; - ok(dom, "The TiltUtils.DOM wasn't found."); - - - is(dom.initCanvas(), null, - "The initCanvas() function shouldn't work if no parent node is set."); - - - dom.parentNode = gBrowser.parentNode; - ok(dom.parentNode, - "The necessary parent node wasn't found."); - - - let canvas = dom.initCanvas(null, { - append: true, - focusable: true, - width: 123, - height: 456, - id: "tilt-test-canvas" - }); - - is(canvas.width, 123, - "The test canvas doesn't have the correct width set."); - is(canvas.height, 456, - "The test canvas doesn't have the correct height set."); - is(canvas.getAttribute("tabindex"), 1, - "The test canvas tab index wasn't set correctly."); - is(canvas.getAttribute("id"), "tilt-test-canvas", - "The test canvas doesn't have the correct id set."); - ok(dom.parentNode.ownerDocument.getElementById(canvas.id), - "A canvas should be appended to the parent node if specified."); - canvas.parentNode.removeChild(canvas); - - let canvas2 = dom.initCanvas(null, { id: "tilt-test-canvas2" }); - - is(canvas2.width, dom.parentNode.clientWidth, - "The second test canvas doesn't have the implicit width set."); - is(canvas2.height, dom.parentNode.clientHeight, - "The second test canvas doesn't have the implicit height set."); - is(canvas2.id, "tilt-test-canvas2", - "The second test canvas doesn't have the correct id set."); - is(dom.parentNode.ownerDocument.getElementById(canvas2.id), null, - "A canvas shouldn't be appended to the parent node if not specified."); - - - dom.parentNode = null; - is(dom.parentNode, null, - "The necessary parent node shouldn't be found anymore."); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils05.js b/devtools/client/tilt/test/browser_tilt_utils05.js deleted file mode 100644 index c73247e2dfc1..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils05.js +++ /dev/null @@ -1,101 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const STACK_THICKNESS = 15; - -function init(callback) { - let iframe = gBrowser.ownerDocument.createElement("iframe"); - - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad, true); - callback(iframe); - - gBrowser.parentNode.removeChild(iframe); - finish(); - }, true); - - iframe.setAttribute("src", ["data:text/html,", - "", - "", - "", - "", - "", - "", - "", - "
", - "", - "
", - "", - "" - ].join("")); - - gBrowser.parentNode.appendChild(iframe); -} - -function test() { - waitForExplicitFinish(); - ok(TiltUtils, "The TiltUtils object doesn't exist."); - - let dom = TiltUtils.DOM; - ok(dom, "The TiltUtils.DOM wasn't found."); - - init(function(iframe) { - let cwDimensions = dom.getContentWindowDimensions(iframe.contentWindow); - - is(cwDimensions.width - iframe.contentWindow.scrollMaxX, - iframe.contentWindow.innerWidth, - "The content window width wasn't calculated correctly."); - is(cwDimensions.height - iframe.contentWindow.scrollMaxY, - iframe.contentWindow.innerHeight, - "The content window height wasn't calculated correctly."); - - let nodeCoordinates = getRect( - gBrowser.contentWindow, - iframe.contentDocument.getElementById("test-div"), iframe.contentWindow); - - let frameOffset = getIframeContentOffset(iframe); - let frameRect = iframe.getBoundingClientRect(); - - is(nodeCoordinates.top, frameRect.top + frameOffset[0] + 98, - "The node coordinates top value wasn't calculated correctly."); - is(nodeCoordinates.left, frameRect.left + frameOffset[1] + 76, - "The node coordinates left value wasn't calculated correctly."); - is(nodeCoordinates.width, 123, - "The node coordinates width value wasn't calculated correctly."); - is(nodeCoordinates.height, 456, - "The node coordinates height value wasn't calculated correctly."); - - - let store = dom.traverse(iframe.contentWindow); - - let expected = [ - { name: "html", depth: 0 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "head", depth: 1 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "body", depth: 1 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "style", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "script", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "div", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "span", depth: 3 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - ]; - - is(store.nodes.length, expected.length, - "The traverse() function didn't walk the correct number of nodes."); - is(store.info.length, expected.length, - "The traverse() function didn't examine the correct number of nodes."); - - for (let i = 0; i < expected.length; i++) { - is(store.info[i].name, expected[i].name, - "traversed node " + (i + 1) + " isn't the expected one."); - is(store.info[i].coord.depth, expected[i].depth, - "traversed node " + (i + 1) + " doesn't have the expected depth."); - is(store.info[i].coord.thickness, expected[i].thickness, - "traversed node " + (i + 1) + " doesn't have the expected thickness."); - } - }); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils06.js b/devtools/client/tilt/test/browser_tilt_utils06.js deleted file mode 100644 index 375201384a0b..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils06.js +++ /dev/null @@ -1,44 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var someObject = { - a: 1, - func: function() - { - this.b = 2; - } -}; - -var anotherObject = { - _finalize: function() - { - someObject.c = 3; - } -}; - -function test() { - ok(TiltUtils, "The TiltUtils object doesn't exist."); - - TiltUtils.bindObjectFunc(someObject, "", anotherObject); - someObject.func(); - - is(someObject.a, 1, - "The bindObjectFunc() messed the non-function members of the object."); - isnot(someObject.b, 2, - "The bindObjectFunc() didn't ignore the old scope correctly."); - is(anotherObject.b, 2, - "The bindObjectFunc() didn't set the new scope correctly."); - - - TiltUtils.destroyObject(anotherObject); - is(someObject.c, 3, - "The finalize function wasn't called when an object was destroyed."); - - - TiltUtils.destroyObject(someObject); - is(typeof someObject.a, "undefined", - "Not all members of the destroyed object were deleted."); - is(typeof someObject.func, "undefined", - "Not all function members of the destroyed object were deleted."); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils07.js b/devtools/client/tilt/test/browser_tilt_utils07.js deleted file mode 100644 index 226049224855..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils07.js +++ /dev/null @@ -1,159 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const STACK_THICKNESS = 15; - -function init(callback) { - let iframe = gBrowser.ownerDocument.createElement("iframe"); - - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad, true); - callback(iframe); - - gBrowser.parentNode.removeChild(iframe); - finish(); - }, true); - - iframe.setAttribute("src", ["data:text/html,", - "", - "", - "", - "", - "", - "
", - "", - "" - ].join(""), - "' />", - "", - "", - "", - "" - ].join(""), - "' />", - "", - "", - "", - "", - "", - "" - ].join(""), - "' />", - "", - "", - "", - "" - ].join(""), - "' />", - "", - "" - ].join("")); - - gBrowser.parentNode.appendChild(iframe); -} - -function test() { - waitForExplicitFinish(); - ok(TiltUtils, "The TiltUtils object doesn't exist."); - - let dom = TiltUtils.DOM; - ok(dom, "The TiltUtils.DOM wasn't found."); - - init(function(iframe) { - let cwDimensions = dom.getContentWindowDimensions(iframe.contentWindow); - - is(cwDimensions.width - iframe.contentWindow.scrollMaxX, - iframe.contentWindow.innerWidth, - "The content window width wasn't calculated correctly."); - is(cwDimensions.height - iframe.contentWindow.scrollMaxY, - iframe.contentWindow.innerHeight, - "The content window height wasn't calculated correctly."); - - let nodeCoordinates = getRect( - gBrowser.contentWindow, - iframe.contentDocument.getElementById("test-div"), iframe.contentWindow); - - let frameOffset = getIframeContentOffset(iframe); - let frameRect = iframe.getBoundingClientRect(); - - is(nodeCoordinates.top, frameRect.top + frameOffset[0], - "The node coordinates top value wasn't calculated correctly."); - is(nodeCoordinates.left, frameRect.left + frameOffset[1], - "The node coordinates left value wasn't calculated correctly."); - is(nodeCoordinates.width, 123, - "The node coordinates width value wasn't calculated correctly."); - is(nodeCoordinates.height, 456, - "The node coordinates height value wasn't calculated correctly."); - - - let store = dom.traverse(iframe.contentWindow); - - let expected = [ - { name: "html", depth: 0 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "head", depth: 1 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "body", depth: 1 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "div", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "span", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "iframe", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "span", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "iframe", depth: 2 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "html", depth: 3 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "html", depth: 3 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "head", depth: 4 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "body", depth: 4 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "head", depth: 4 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "body", depth: 4 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "span", depth: 5 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "div", depth: 5 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - ]; - - is(store.nodes.length, expected.length, - "The traverse() function didn't walk the correct number of nodes."); - is(store.info.length, expected.length, - "The traverse() function didn't examine the correct number of nodes."); - - for (let i = 0; i < expected.length; i++) { - is(store.info[i].name, expected[i].name, - "traversed node " + (i + 1) + " isn't the expected one."); - is(store.info[i].coord.depth, expected[i].depth, - "traversed node " + (i + 1) + " doesn't have the expected depth."); - is(store.info[i].coord.thickness, expected[i].thickness, - "traversed node " + (i + 1) + " doesn't have the expected thickness."); - } - }); -} diff --git a/devtools/client/tilt/test/browser_tilt_utils08.js b/devtools/client/tilt/test/browser_tilt_utils08.js deleted file mode 100644 index 797c9e7a7766..000000000000 --- a/devtools/client/tilt/test/browser_tilt_utils08.js +++ /dev/null @@ -1,85 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const STACK_THICKNESS = 15; - -function init(callback) { - let iframe = gBrowser.ownerDocument.createElement("iframe"); - - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad, true); - callback(iframe); - - gBrowser.parentNode.removeChild(iframe); - finish(); - }, true); - - iframe.setAttribute("src", ["data:text/html,", - "", - "", - "", - "
", - "

Foo

", - "
", - "Bar", - "
", - "
", - "
", - "", - "" - ].join("")); - - gBrowser.parentNode.appendChild(iframe); -} - -function nodeCallback(aContentWindow, aNode, aParentPosition) { - let coord = TiltUtils.DOM.getNodePosition(aContentWindow, aNode, aParentPosition); - - if (aNode.localName != "div") - coord.thickness = 0; - - if (aNode.localName == "span") - coord.depth += STACK_THICKNESS; - - return coord; -} - -function test() { - waitForExplicitFinish(); - ok(TiltUtils, "The TiltUtils object doesn't exist."); - - let dom = TiltUtils.DOM; - ok(dom, "The TiltUtils.DOM wasn't found."); - - init(function(iframe) { - let store = dom.traverse(iframe.contentWindow, { - nodeCallback: nodeCallback - }); - - let expected = [ - { name: "html", depth: 0 * STACK_THICKNESS, thickness: 0 }, - { name: "head", depth: 0 * STACK_THICKNESS, thickness: 0 }, - { name: "body", depth: 0 * STACK_THICKNESS, thickness: 0 }, - { name: "div", depth: 0 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "p", depth: 1 * STACK_THICKNESS, thickness: 0 }, - { name: "div", depth: 1 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "div", depth: 1 * STACK_THICKNESS, thickness: STACK_THICKNESS }, - { name: "span", depth: 3 * STACK_THICKNESS, thickness: 0 }, - ]; - - is(store.nodes.length, expected.length, - "The traverse() function didn't walk the correct number of nodes."); - is(store.info.length, expected.length, - "The traverse() function didn't examine the correct number of nodes."); - - for (let i = 0; i < expected.length; i++) { - is(store.info[i].name, expected[i].name, - "traversed node " + (i + 1) + " isn't the expected one."); - is(store.info[i].coord.depth, expected[i].depth, - "traversed node " + (i + 1) + " doesn't have the expected depth."); - is(store.info[i].coord.thickness, expected[i].thickness, - "traversed node " + (i + 1) + " doesn't have the expected thickness."); - } - }); -} diff --git a/devtools/client/tilt/test/browser_tilt_visualizer.js b/devtools/client/tilt/test/browser_tilt_visualizer.js deleted file mode 100644 index 74f906ff02b3..000000000000 --- a/devtools/client/tilt/test/browser_tilt_visualizer.js +++ /dev/null @@ -1,128 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping notifications test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping visualizer test because WebGL isn't supported."); - return; - } - - let webGLError = false; - let webGLLoad = false; - - let visualizer = new TiltVisualizer({ - chromeWindow: window, - contentWindow: gBrowser.selectedBrowser.contentWindow, - parentNode: gBrowser.selectedBrowser.parentNode, - notifications: Tilt.NOTIFICATIONS, - tab: gBrowser.selectedTab, - - onError: function onWebGLError() - { - webGLError = true; - }, - - onLoad: function onWebGLLoad() - { - webGLLoad = true; - } - }); - visualizer.init(); - - ok(webGLError ^ webGLLoad, - "The WebGL context should either be created or not."); - - if (webGLError) { - info("Skipping visualizer test because WebGL couldn't be initialized."); - return; - } - - ok(visualizer.canvas, - "Visualizer constructor should have created a child canvas object."); - ok(visualizer.presenter, - "Visualizer constructor should have created a child presenter object."); - ok(visualizer.controller, - "Visualizer constructor should have created a child controller object."); - ok(visualizer.isInitialized(), - "The visualizer should have been initialized properly."); - ok(visualizer.presenter.isInitialized(), - "The visualizer presenter should have been initialized properly."); - ok(visualizer.controller.isInitialized(), - "The visualizer controller should have been initialized properly."); - - testPresenter(visualizer.presenter); - testController(visualizer.controller); - - visualizer.removeOverlay(); - is(visualizer.canvas.parentNode, null, - "The visualizer canvas wasn't removed from the parent node."); - - visualizer.cleanup(); - is(visualizer.presenter, undefined, - "The visualizer presenter wasn't destroyed."); - is(visualizer.controller, undefined, - "The visualizer controller wasn't destroyed."); - is(visualizer.canvas, undefined, - "The visualizer canvas wasn't destroyed."); -} - -function testPresenter(presenter) { - ok(presenter._renderer, - "The presenter renderer wasn't initialized properly."); - ok(presenter._visualizationProgram, - "The presenter visualizationProgram wasn't initialized properly."); - ok(presenter._texture, - "The presenter texture wasn't initialized properly."); - ok(!presenter._meshStacks, - "The presenter meshStacks shouldn't be initialized yet."); - ok(!presenter._meshWireframe, - "The presenter meshWireframe shouldn't be initialized yet."); - ok(presenter._traverseData, - "The presenter nodesInformation wasn't initialized properly."); - ok(presenter._highlight, - "The presenter highlight wasn't initialized properly."); - ok(presenter._highlight.disabled, - "The presenter highlight should be initially disabled."); - ok(isApproxVec(presenter._highlight.v0, [0, 0, 0]), - "The presenter highlight first vertex should be initially zeroed."); - ok(isApproxVec(presenter._highlight.v1, [0, 0, 0]), - "The presenter highlight second vertex should be initially zeroed."); - ok(isApproxVec(presenter._highlight.v2, [0, 0, 0]), - "The presenter highlight third vertex should be initially zeroed."); - ok(isApproxVec(presenter._highlight.v3, [0, 0, 0]), - "The presenter highlight fourth vertex should be initially zeroed."); - ok(presenter.transforms, - "The presenter transforms wasn't initialized properly."); - is(presenter.transforms.zoom, 1, - "The presenter transforms zoom should be initially 1."); - ok(isApproxVec(presenter.transforms.offset, [0, 0, 0]), - "The presenter transforms offset should be initially zeroed."); - ok(isApproxVec(presenter.transforms.translation, [0, 0, 0]), - "The presenter transforms translation should be initially zeroed."); - ok(isApproxVec(presenter.transforms.rotation, [0, 0, 0, 1]), - "The presenter transforms rotation should be initially set to identity."); - - presenter.setTranslation([1, 2, 3]); - presenter.setRotation([5, 6, 7, 8]); - - ok(isApproxVec(presenter.transforms.translation, [1, 2, 3]), - "The presenter transforms translation wasn't modified as it should"); - ok(isApproxVec(presenter.transforms.rotation, [5, 6, 7, 8]), - "The presenter transforms rotation wasn't modified as it should"); - ok(presenter._redraw, - "The new transforms should have issued a redraw request."); -} - -function testController(controller) { - ok(controller.arcball, - "The controller arcball wasn't initialized properly."); - ok(!controller.coordinates, - "The presenter meshWireframe shouldn't be initialized yet."); -} diff --git a/devtools/client/tilt/test/browser_tilt_zoom.js b/devtools/client/tilt/test/browser_tilt_zoom.js deleted file mode 100644 index 0efb4c38a52a..000000000000 --- a/devtools/client/tilt/test/browser_tilt_zoom.js +++ /dev/null @@ -1,117 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -const ZOOM = 2; -const RESIZE = 50; -var tiltOpened = false; - -function test() { - if (!isTiltEnabled()) { - aborting(); - info("Skipping controller test because Tilt isn't enabled."); - return; - } - if (!isWebGLSupported()) { - aborting(); - info("Skipping controller test because WebGL isn't supported."); - return; - } - - waitForExplicitFinish(); - - if (window.windowState == window.STATE_MAXIMIZED) { - registerCleanupFunction(function () { - window.maximize(); - }); - - window.addEventListener("resize", function onResize(event) { - if (event.target == window) { - window.removeEventListener("resize", onResize, false); - executeSoon(testTilt); - } - }, false); - - window.restore(); - } else { - testTilt(); - } -} - -function testTilt() { - createTab(function() { - TiltUtils.setDocumentZoom(window, ZOOM); - - createTilt({ - onTiltOpen: function(instance) - { - tiltOpened = true; - - ok(isApprox(instance.presenter._getPageZoom(), ZOOM), - "The Highlighter zoom doesn't have the expected results."); - - ok(isApprox(instance.presenter.transforms.zoom, ZOOM), - "The presenter transforms zoom wasn't initially set correctly."); - - let contentWindow = gBrowser.selectedBrowser.contentWindow; - let initialWidth = contentWindow.innerWidth; - let initialHeight = contentWindow.innerHeight; - - let renderer = instance.presenter._renderer; - let arcball = instance.controller.arcball; - - ok(isApprox(contentWindow.innerWidth * ZOOM, renderer.width, 1), - "The renderer width wasn't set correctly before the resize."); - ok(isApprox(contentWindow.innerHeight * ZOOM, renderer.height, 1), - "The renderer height wasn't set correctly before the resize."); - - ok(isApprox(contentWindow.innerWidth * ZOOM, arcball.width, 1), - "The arcball width wasn't set correctly before the resize."); - ok(isApprox(contentWindow.innerHeight * ZOOM, arcball.height, 1), - "The arcball height wasn't set correctly before the resize."); - - window.addEventListener("resize", onResize, false); - window.resizeBy(-RESIZE * ZOOM, -RESIZE * ZOOM); - - function onResize(event) { - if (event.target == window) { - window.removeEventListener("resize", onResize, false); - executeSoon(afterResize); - } - } - - function afterResize() { - ok(isApprox(contentWindow.innerWidth + RESIZE, initialWidth, 1), - "The content window width wasn't set correctly after the resize."); - ok(isApprox(contentWindow.innerHeight + RESIZE, initialHeight, 1), - "The content window height wasn't set correctly after the resize."); - - ok(isApprox(contentWindow.innerWidth * ZOOM, renderer.width, 1), - "The renderer width wasn't set correctly after the resize."); - ok(isApprox(contentWindow.innerHeight * ZOOM, renderer.height, 1), - "The renderer height wasn't set correctly after the resize."); - - ok(isApprox(contentWindow.innerWidth * ZOOM, arcball.width, 1), - "The arcball width wasn't set correctly after the resize."); - ok(isApprox(contentWindow.innerHeight * ZOOM, arcball.height, 1), - "The arcball height wasn't set correctly after the resize."); - - window.resizeBy(RESIZE * ZOOM, RESIZE * ZOOM); - - Services.obs.addObserver(cleanup, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - } - } - }, false, function suddenDeath() - { - ok(false, "Tilt could not be initialized properly."); - cleanup(); - }); - }); -} - -function cleanup() { - if (tiltOpened) { Services.obs.removeObserver(cleanup, DESTROYED); } - gBrowser.removeCurrentTab(); - finish(); -} diff --git a/devtools/client/tilt/test/head.js b/devtools/client/tilt/test/head.js deleted file mode 100644 index 500a72e465bd..000000000000 --- a/devtools/client/tilt/test/head.js +++ /dev/null @@ -1,214 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -var {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); -var TiltManager = require("devtools/client/tilt/tilt").TiltManager; -var TiltGL = require("devtools/client/tilt/tilt-gl"); -var {EPSILON, TiltMath, vec3, mat3, mat4, quat4} = require("devtools/client/tilt/tilt-math"); -var TiltUtils = require("devtools/client/tilt/tilt-utils"); -var {TiltVisualizer} = require("devtools/client/tilt/tilt-visualizer"); -var DevToolsUtils = require("devtools/shared/DevToolsUtils"); -var {getRect, getIframeContentOffset} = require("devtools/shared/layout/utils"); - - -const DEFAULT_HTML = "data:text/html," + - "" + - "" + - "" + - "" + - "Three Laws" + - "" + - "" + - "
" + - "A robot may not injure a human being or, through inaction, allow a " + - "human being to come to harm." + - "
" + - "
" + - "A robot must obey the orders given to it by human beings, except " + - "where such orders would conflict with the First Law." + - "
" + - "
" + - "A robot must protect its own existence as long as such protection " + - "does not conflict with the First or Second Laws." + - "
" + - "
" + - "I like bacon." + - "
" + - "" + - ""; - -var Tilt = TiltManager.getTiltForBrowser(window); - -const STARTUP = Tilt.NOTIFICATIONS.STARTUP; -const INITIALIZING = Tilt.NOTIFICATIONS.INITIALIZING; -const INITIALIZED = Tilt.NOTIFICATIONS.INITIALIZED; -const DESTROYING = Tilt.NOTIFICATIONS.DESTROYING; -const BEFORE_DESTROYED = Tilt.NOTIFICATIONS.BEFORE_DESTROYED; -const DESTROYED = Tilt.NOTIFICATIONS.DESTROYED; -const SHOWN = Tilt.NOTIFICATIONS.SHOWN; -const HIDDEN = Tilt.NOTIFICATIONS.HIDDEN; -const HIGHLIGHTING = Tilt.NOTIFICATIONS.HIGHLIGHTING; -const UNHIGHLIGHTING = Tilt.NOTIFICATIONS.UNHIGHLIGHTING; -const NODE_REMOVED = Tilt.NOTIFICATIONS.NODE_REMOVED; - -const TILT_ENABLED = Services.prefs.getBoolPref("devtools.tilt.enabled"); - -DevToolsUtils.testing = true; -SimpleTest.registerCleanupFunction(() => { - DevToolsUtils.testing = false; -}); - -function isTiltEnabled() { - info("Apparently, Tilt is" + (TILT_ENABLED ? "" : " not") + " enabled."); - return TILT_ENABLED; -} - -function isWebGLSupported() { - let supported = !TiltGL.isWebGLForceEnabled() && - TiltGL.isWebGLSupported() && - TiltGL.create3DContext(createCanvas()); - - info("Apparently, WebGL is" + (supported ? "" : " not") + " supported."); - return supported; -} - -function isApprox(num1, num2, delta) { - if (Math.abs(num1 - num2) > (delta || EPSILON)) { - info("isApprox expected " + num1 + ", got " + num2 + " instead."); - return false; - } - return true; -} - -function isApproxVec(vec1, vec2, delta) { - vec1 = Array.prototype.slice.call(vec1); - vec2 = Array.prototype.slice.call(vec2); - - if (vec1.length !== vec2.length) { - return false; - } - for (let i = 0, len = vec1.length; i < len; i++) { - if (!isApprox(vec1[i], vec2[i], delta)) { - info("isApproxVec expected [" + vec1 + "], got [" + vec2 + "] instead."); - return false; - } - } - return true; -} - -function isEqualVec(vec1, vec2) { - vec1 = Array.prototype.slice.call(vec1); - vec2 = Array.prototype.slice.call(vec2); - - if (vec1.length !== vec2.length) { - return false; - } - for (let i = 0, len = vec1.length; i < len; i++) { - if (vec1[i] !== vec2[i]) { - info("isEqualVec expected [" + vec1 + "], got [" + vec2 + "] instead."); - return false; - } - } - return true; -} - -function createCanvas() { - return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); -} - - -function createTab(callback, location) { - info("Creating a tab, with callback " + typeof callback + - ", and location " + location + "."); - - let tab = gBrowser.selectedTab = gBrowser.addTab(); - - gBrowser.selectedBrowser.addEventListener("load", function onLoad() { - gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); - callback(tab); - }, true); - - gBrowser.selectedBrowser.contentWindow.location = location || DEFAULT_HTML; - return tab; -} - - -function createTilt(callbacks, close, suddenDeath) { - info("Creating Tilt, with callbacks {" + Object.keys(callbacks) + "}" + - ", autoclose param " + close + - ", and sudden death handler " + typeof suddenDeath + "."); - - handleFailure(suddenDeath); - - Services.prefs.setBoolPref("webgl.verbose", true); - TiltUtils.Output.suppressAlerts = true; - - info("Attempting to start Tilt."); - Services.obs.addObserver(onTiltOpen, INITIALIZING, false); - Tilt.toggle(); - - function onTiltOpen() { - info("Tilt was opened."); - Services.obs.removeObserver(onTiltOpen, INITIALIZING); - - executeSoon(function() { - if ("function" === typeof callbacks.onTiltOpen) { - info("Calling 'onTiltOpen'."); - callbacks.onTiltOpen(Tilt.visualizers[Tilt.currentWindowId]); - } - if (close) { - executeSoon(function() { - info("Attempting to close Tilt."); - Services.obs.addObserver(onTiltClose, DESTROYED, false); - Tilt.destroy(Tilt.currentWindowId); - }); - } - }); - } - - function onTiltClose() { - info("Tilt was closed."); - Services.obs.removeObserver(onTiltClose, DESTROYED); - - executeSoon(function() { - if ("function" === typeof callbacks.onTiltClose) { - info("Calling 'onTiltClose'."); - callbacks.onTiltClose(); - } - if ("function" === typeof callbacks.onEnd) { - info("Calling 'onEnd'."); - callbacks.onEnd(); - } - }); - } - - function handleFailure(suddenDeath) { - Tilt.failureCallback = function() { - info("Tilt FAIL."); - Services.obs.removeObserver(onTiltOpen, INITIALIZING); - - info("Now relying on sudden death handler " + typeof suddenDeath + "."); - suddenDeath && suddenDeath(); - } - } -} - -function getPickablePoint(presenter) { - let vertices = presenter._meshStacks[0].vertices.components; - - let topLeft = vec3.create([vertices[0], vertices[1], vertices[2]]); - let bottomRight = vec3.create([vertices[6], vertices[7], vertices[8]]); - let center = vec3.lerp(topLeft, bottomRight, 0.5, []); - - let renderer = presenter._renderer; - let viewport = [0, 0, renderer.width, renderer.height]; - - return vec3.project(center, viewport, renderer.mvMatrix, renderer.projMatrix); -} - -function aborting() { - // Tilt aborting and we need at least one pass, fail or todo so let's add a - // dummy pass. - ok(true, "Test aborted early."); -} diff --git a/devtools/client/tilt/tilt-commands.js b/devtools/client/tilt/tilt-commands.js deleted file mode 100644 index 4696d54b4117..000000000000 --- a/devtools/client/tilt/tilt-commands.js +++ /dev/null @@ -1,228 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const l10n = require("gcli/l10n"); - -// Fetch TiltManager using the current loader, but don't save a -// reference to it, because it might change with a tool reload. -// We can clean this up once the command line is loadered. -Object.defineProperty(this, "TiltManager", { - get: function() { - return require("devtools/client/tilt/tilt").TiltManager; - }, - enumerable: true -}); - -exports.items = [ -{ - name: "tilt", - description: l10n.lookup("tiltDesc"), - manual: l10n.lookup("tiltManual"), - hidden: true -}, -{ - name: "tilt open", - runAt: "client", - description: l10n.lookup("tiltOpenDesc"), - manual: l10n.lookup("tiltOpenManual"), - hidden: true, - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - if (!Tilt.currentInstance) { - Tilt.toggle(); - } - } -}, -{ - name: "tilt toggle", - runAt: "client", - buttonId: "command-button-tilt", - buttonClass: "command-button command-button-invertable", - tooltipText: l10n.lookup("tiltToggleTooltip"), - hidden: true, - state: { - isChecked: function(aTarget) { - if (!aTarget.tab) { - return false; - } - let browserWindow = aTarget.tab.ownerDocument.defaultView; - return !!TiltManager.getTiltForBrowser(browserWindow).currentInstance; - }, - onChange: function(aTarget, aChangeHandler) { - if (!aTarget.tab) { - return; - } - let browserWindow = aTarget.tab.ownerDocument.defaultView; - let tilt = TiltManager.getTiltForBrowser(browserWindow); - tilt.on("change", aChangeHandler); - }, - offChange: function(aTarget, aChangeHandler) { - if (!aTarget.tab) { - return; - } - let browserWindow = aTarget.tab.ownerDocument.defaultView; - let tilt = TiltManager.getTiltForBrowser(browserWindow); - tilt.off("change", aChangeHandler); - }, - }, - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - Tilt.toggle(); - } -}, -{ - name: "tilt translate", - runAt: "client", - description: l10n.lookup("tiltTranslateDesc"), - manual: l10n.lookup("tiltTranslateManual"), - hidden: true, - params: [ - { - name: "x", - type: "number", - defaultValue: 0, - description: l10n.lookup("tiltTranslateXDesc"), - manual: l10n.lookup("tiltTranslateXManual") - }, - { - name: "y", - type: "number", - defaultValue: 0, - description: l10n.lookup("tiltTranslateYDesc"), - manual: l10n.lookup("tiltTranslateYManual") - } - ], - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - if (Tilt.currentInstance) { - Tilt.currentInstance.controller.arcball.translate([args.x, args.y]); - } - } -}, -{ - name: "tilt rotate", - runAt: "client", - description: l10n.lookup("tiltRotateDesc"), - manual: l10n.lookup("tiltRotateManual"), - hidden: true, - params: [ - { - name: "x", - type: { name: 'number', min: -360, max: 360, step: 10 }, - defaultValue: 0, - description: l10n.lookup("tiltRotateXDesc"), - manual: l10n.lookup("tiltRotateXManual") - }, - { - name: "y", - type: { name: 'number', min: -360, max: 360, step: 10 }, - defaultValue: 0, - description: l10n.lookup("tiltRotateYDesc"), - manual: l10n.lookup("tiltRotateYManual") - }, - { - name: "z", - type: { name: 'number', min: -360, max: 360, step: 10 }, - defaultValue: 0, - description: l10n.lookup("tiltRotateZDesc"), - manual: l10n.lookup("tiltRotateZManual") - } - ], - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - if (Tilt.currentInstance) { - Tilt.currentInstance.controller.arcball.rotate([args.x, args.y, args.z]); - } - } -}, -{ - name: "tilt zoom", - runAt: "client", - description: l10n.lookup("tiltZoomDesc"), - manual: l10n.lookup("tiltZoomManual"), - hidden: true, - params: [ - { - name: "zoom", - type: { name: 'number' }, - description: l10n.lookup("tiltZoomAmountDesc"), - manual: l10n.lookup("tiltZoomAmountManual") - } - ], - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - - if (Tilt.currentInstance) { - Tilt.currentInstance.controller.arcball.zoom(-args.zoom); - } - } -}, -{ - name: "tilt reset", - runAt: "client", - description: l10n.lookup("tiltResetDesc"), - manual: l10n.lookup("tiltResetManual"), - hidden: true, - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - - if (Tilt.currentInstance) { - Tilt.currentInstance.controller.arcball.reset(); - } - } -}, -{ - name: "tilt close", - runAt: "client", - description: l10n.lookup("tiltCloseDesc"), - manual: l10n.lookup("tiltCloseManual"), - hidden: true, - exec: function(args, context) { - if (isMultiProcess(context)) { - return l10n.lookupFormat("notAvailableInE10S", [this.name]); - } - - let chromeWindow = context.environment.chromeDocument.defaultView; - let Tilt = TiltManager.getTiltForBrowser(chromeWindow); - - Tilt.destroy(Tilt.currentWindowId); - } -} -]; - -function isMultiProcess(context) { - return !context.environment.window; -} diff --git a/devtools/client/tilt/tilt-gl.js b/devtools/client/tilt/tilt-gl.js deleted file mode 100644 index 7ada86b7f08b..000000000000 --- a/devtools/client/tilt/tilt-gl.js +++ /dev/null @@ -1,1594 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {Cc, Ci, Cu} = require("chrome"); - -var TiltUtils = require("devtools/client/tilt/tilt-utils"); -var {TiltMath, mat4} = require("devtools/client/tilt/tilt-math"); -var Services = require("Services"); - -const WEBGL_CONTEXT_NAME = "experimental-webgl"; - - -/** - * Module containing thin wrappers around low-level WebGL functions. - */ -var TiltGL = {}; -module.exports = TiltGL; - -/** - * Contains commonly used helper methods used in any 3D application. - * - * @param {HTMLCanvasElement} aCanvas - * the canvas element used for rendering - * @param {Function} onError - * optional, function called if initialization failed - * @param {Function} onLoad - * optional, function called if initialization worked - */ -TiltGL.Renderer = function TGL_Renderer(aCanvas, onError, onLoad) -{ - /** - * The WebGL context obtained from the canvas element, used for drawing. - */ - this.context = TiltGL.create3DContext(aCanvas); - - // check if the context was created successfully - if (!this.context) { - TiltUtils.Output.alert("Firefox", TiltUtils.L10n.get("initTilt.error")); - TiltUtils.Output.error(TiltUtils.L10n.get("initWebGL.error")); - - if ("function" === typeof onError) { - onError(); - } - return; - } - - // set the default clear color and depth buffers - this.context.clearColor(0, 0, 0, 0); - this.context.clearDepth(1); - - /** - * Variables representing the current framebuffer width and height. - */ - this.width = aCanvas.width; - this.height = aCanvas.height; - this.initialWidth = this.width; - this.initialHeight = this.height; - - /** - * The current model view matrix. - */ - this.mvMatrix = mat4.identity(mat4.create()); - - /** - * The current projection matrix. - */ - this.projMatrix = mat4.identity(mat4.create()); - - /** - * The current fill color applied to any objects which can be filled. - * These are rectangles, circles, boxes, 2d or 3d primitives in general. - */ - this._fillColor = []; - - /** - * The current stroke color applied to any objects which can be stroked. - * This property mostly refers to lines. - */ - this._strokeColor = []; - - /** - * Variable representing the current stroke weight. - */ - this._strokeWeightValue = 0; - - /** - * A shader useful for drawing vertices with only a color component. - */ - this._colorShader = new TiltGL.Program(this.context, { - vs: TiltGL.ColorShader.vs, - fs: TiltGL.ColorShader.fs, - attributes: ["vertexPosition"], - uniforms: ["mvMatrix", "projMatrix", "fill"] - }); - - // create helper functions to create shaders, meshes, buffers and textures - this.Program = - TiltGL.Program.bind(TiltGL.Program, this.context); - this.VertexBuffer = - TiltGL.VertexBuffer.bind(TiltGL.VertexBuffer, this.context); - this.IndexBuffer = - TiltGL.IndexBuffer.bind(TiltGL.IndexBuffer, this.context); - this.Texture = - TiltGL.Texture.bind(TiltGL.Texture, this.context); - - // set the default mvp matrices, tint, fill, stroke and other visual props. - this.defaults(); - - // the renderer was created successfully - if ("function" === typeof onLoad) { - onLoad(); - } -}; - -TiltGL.Renderer.prototype = { - - /** - * Clears the color and depth buffers. - */ - clear: function TGLR_clear() - { - let gl = this.context; - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - }, - - /** - * Sets if depth testing should be enabled or not. - * Disabling could be useful when handling transparency (for example). - * - * @param {Boolean} aEnabledFlag - * true if depth testing should be enabled - */ - depthTest: function TGLR_depthTest(aEnabledFlag) - { - let gl = this.context; - - if (aEnabledFlag) { - gl.enable(gl.DEPTH_TEST); - } else { - gl.disable(gl.DEPTH_TEST); - } - }, - - /** - * Sets if stencil testing should be enabled or not. - * - * @param {Boolean} aEnabledFlag - * true if stencil testing should be enabled - */ - stencilTest: function TGLR_stencilTest(aEnabledFlag) - { - let gl = this.context; - - if (aEnabledFlag) { - gl.enable(gl.STENCIL_TEST); - } else { - gl.disable(gl.STENCIL_TEST); - } - }, - - /** - * Sets cull face, either "front", "back" or disabled. - * - * @param {String} aModeFlag - * blending mode, either "front", "back", "both" or falsy - */ - cullFace: function TGLR_cullFace(aModeFlag) - { - let gl = this.context; - - switch (aModeFlag) { - case "front": - gl.enable(gl.CULL_FACE); - gl.cullFace(gl.FRONT); - break; - case "back": - gl.enable(gl.CULL_FACE); - gl.cullFace(gl.BACK); - break; - case "both": - gl.enable(gl.CULL_FACE); - gl.cullFace(gl.FRONT_AND_BACK); - break; - default: - gl.disable(gl.CULL_FACE); - } - }, - - /** - * Specifies the orientation of front-facing polygons. - * - * @param {String} aModeFlag - * either "cw" or "ccw" - */ - frontFace: function TGLR_frontFace(aModeFlag) - { - let gl = this.context; - - switch (aModeFlag) { - case "cw": - gl.frontFace(gl.CW); - break; - case "ccw": - gl.frontFace(gl.CCW); - break; - } - }, - - /** - * Sets blending, either "alpha" or "add" (additive blending). - * Anything else disables blending. - * - * @param {String} aModeFlag - * blending mode, either "alpha", "add" or falsy - */ - blendMode: function TGLR_blendMode(aModeFlag) - { - let gl = this.context; - - switch (aModeFlag) { - case "alpha": - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - break; - case "add": - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE); - break; - default: - gl.disable(gl.BLEND); - } - }, - - /** - * Helper function to activate the color shader. - * - * @param {TiltGL.VertexBuffer} aVerticesBuffer - * a buffer of vertices positions - * @param {Array} aColor - * the color fill to be used as [r, g, b, a] with 0..1 range - * @param {Array} aMvMatrix - * the model view matrix - * @param {Array} aProjMatrix - * the projection matrix - */ - useColorShader: function TGLR_useColorShader( - aVerticesBuffer, aColor, aMvMatrix, aProjMatrix) - { - let program = this._colorShader; - - // use this program - program.use(); - - // bind the attributes and uniforms as necessary - program.bindVertexBuffer("vertexPosition", aVerticesBuffer); - program.bindUniformMatrix("mvMatrix", aMvMatrix || this.mvMatrix); - program.bindUniformMatrix("projMatrix", aProjMatrix || this.projMatrix); - program.bindUniformVec4("fill", aColor || this._fillColor); - }, - - /** - * Draws bound vertex buffers using the specified parameters. - * - * @param {Number} aDrawMode - * WebGL enum, like TRIANGLES - * @param {Number} aCount - * the number of indices to be rendered - */ - drawVertices: function TGLR_drawVertices(aDrawMode, aCount) - { - this.context.drawArrays(aDrawMode, 0, aCount); - }, - - /** - * Draws bound vertex buffers using the specified parameters. - * This function also makes use of an index buffer. - * - * @param {Number} aDrawMode - * WebGL enum, like TRIANGLES - * @param {TiltGL.IndexBuffer} aIndicesBuffer - * indices for the vertices buffer - */ - drawIndexedVertices: function TGLR_drawIndexedVertices( - aDrawMode, aIndicesBuffer) - { - let gl = this.context; - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, aIndicesBuffer._ref); - gl.drawElements(aDrawMode, aIndicesBuffer.numItems, gl.UNSIGNED_SHORT, 0); - }, - - /** - * Sets the current fill color. - * - * @param {Array} aColor - * the color fill to be used as [r, g, b, a] with 0..1 range - * @param {Number} aMultiplyAlpha - * optional, scalar to multiply the alpha element with - */ - fill: function TGLR_fill(aColor, aMultiplyAlpha) - { - let fill = this._fillColor; - - fill[0] = aColor[0]; - fill[1] = aColor[1]; - fill[2] = aColor[2]; - fill[3] = aColor[3] * (aMultiplyAlpha || 1); - }, - - /** - * Sets the current stroke color. - * - * @param {Array} aColor - * the color stroke to be used as [r, g, b, a] with 0..1 range - * @param {Number} aMultiplyAlpha - * optional, scalar to multiply the alpha element with - */ - stroke: function TGLR_stroke(aColor, aMultiplyAlpha) - { - let stroke = this._strokeColor; - - stroke[0] = aColor[0]; - stroke[1] = aColor[1]; - stroke[2] = aColor[2]; - stroke[3] = aColor[3] * (aMultiplyAlpha || 1); - }, - - /** - * Sets the current stroke weight (line width). - * - * @param {Number} aWeight - * the stroke weight - */ - strokeWeight: function TGLR_strokeWeight(aWeight) - { - if (this._strokeWeightValue !== aWeight) { - this._strokeWeightValue = aWeight; - this.context.lineWidth(aWeight); - } - }, - - /** - * Sets a default perspective projection, with the near frustum rectangle - * mapped to the canvas width and height bounds. - */ - perspective: function TGLR_perspective() - { - let fov = 45; - let w = this.width; - let h = this.height; - let x = w / 2; - let y = h / 2; - let z = y / Math.tan(TiltMath.radians(fov) / 2); - let aspect = w / h; - let znear = z / 10; - let zfar = z * 10; - - mat4.perspective(fov, aspect, znear, zfar, this.projMatrix, -1); - mat4.translate(this.projMatrix, [-x, -y, -z]); - mat4.identity(this.mvMatrix); - }, - - /** - * Sets a default orthographic projection (recommended for 2d rendering). - */ - ortho: function TGLR_ortho() - { - mat4.ortho(0, this.width, this.height, 0, -1, 1, this.projMatrix); - mat4.identity(this.mvMatrix); - }, - - /** - * Sets a custom projection matrix. - * @param {Array} matrix: the custom projection matrix to be used - */ - projection: function TGLR_projection(aMatrix) - { - mat4.set(aMatrix, this.projMatrix); - mat4.identity(this.mvMatrix); - }, - - /** - * Resets the model view matrix to identity. - * This is a default matrix with no rotation, no scaling, at (0, 0, 0); - */ - origin: function TGLR_origin() - { - mat4.identity(this.mvMatrix); - }, - - /** - * Transforms the model view matrix with a new matrix. - * Useful for creating custom transformations. - * - * @param {Array} matrix: the matrix to be multiply the model view with - */ - transform: function TGLR_transform(aMatrix) - { - mat4.multiply(this.mvMatrix, aMatrix); - }, - - /** - * Translates the model view by the x, y and z coordinates. - * - * @param {Number} x - * the x amount of translation - * @param {Number} y - * the y amount of translation - * @param {Number} z - * optional, the z amount of translation - */ - translate: function TGLR_translate(x, y, z) - { - mat4.translate(this.mvMatrix, [x, y, z || 0]); - }, - - /** - * Rotates the model view by a specified angle on the x, y and z axis. - * - * @param {Number} angle - * the angle expressed in radians - * @param {Number} x - * the x axis of the rotation - * @param {Number} y - * the y axis of the rotation - * @param {Number} z - * the z axis of the rotation - */ - rotate: function TGLR_rotate(angle, x, y, z) - { - mat4.rotate(this.mvMatrix, angle, [x, y, z]); - }, - - /** - * Rotates the model view by a specified angle on the x axis. - * - * @param {Number} aAngle - * the angle expressed in radians - */ - rotateX: function TGLR_rotateX(aAngle) - { - mat4.rotateX(this.mvMatrix, aAngle); - }, - - /** - * Rotates the model view by a specified angle on the y axis. - * - * @param {Number} aAngle - * the angle expressed in radians - */ - rotateY: function TGLR_rotateY(aAngle) - { - mat4.rotateY(this.mvMatrix, aAngle); - }, - - /** - * Rotates the model view by a specified angle on the z axis. - * - * @param {Number} aAngle - * the angle expressed in radians - */ - rotateZ: function TGLR_rotateZ(aAngle) - { - mat4.rotateZ(this.mvMatrix, aAngle); - }, - - /** - * Scales the model view by the x, y and z coordinates. - * - * @param {Number} x - * the x amount of scaling - * @param {Number} y - * the y amount of scaling - * @param {Number} z - * optional, the z amount of scaling - */ - scale: function TGLR_scale(x, y, z) - { - mat4.scale(this.mvMatrix, [x, y, z || 1]); - }, - - /** - * Performs a custom interpolation between two matrices. - * The result is saved in the first operand. - * - * @param {Array} aMat - * the first matrix - * @param {Array} aMat2 - * the second matrix - * @param {Number} aLerp - * interpolation amount between the two inputs - * @param {Number} aDamping - * optional, scalar adjusting the interpolation amortization - * @param {Number} aBalance - * optional, scalar adjusting the interpolation shift ammount - */ - lerp: function TGLR_lerp(aMat, aMat2, aLerp, aDamping, aBalance) - { - if (aLerp < 0 || aLerp > 1) { - return; - } - - // calculate the interpolation factor based on the damping and step - let f = Math.pow(1 - Math.pow(aLerp, aDamping || 1), 1 / aBalance || 1); - - // interpolate each element from the two matrices - for (let i = 0, len = this.projMatrix.length; i < len; i++) { - aMat[i] = aMat[i] + f * (aMat2[i] - aMat[i]); - } - }, - - /** - * Resets the drawing style to default. - */ - defaults: function TGLR_defaults() - { - this.depthTest(true); - this.stencilTest(false); - this.cullFace(false); - this.frontFace("ccw"); - this.blendMode("alpha"); - this.fill([1, 1, 1, 1]); - this.stroke([0, 0, 0, 1]); - this.strokeWeight(1); - this.perspective(); - this.origin(); - }, - - /** - * Draws a quad composed of four vertices. - * Vertices must be in clockwise order, or else drawing will be distorted. - * Do not abuse this function, it is quite slow. - * - * @param {Array} aV0 - * the [x, y, z] position of the first triangle point - * @param {Array} aV1 - * the [x, y, z] position of the second triangle point - * @param {Array} aV2 - * the [x, y, z] position of the third triangle point - * @param {Array} aV3 - * the [x, y, z] position of the fourth triangle point - */ - quad: function TGLR_quad(aV0, aV1, aV2, aV3) - { - let gl = this.context; - let fill = this._fillColor; - let stroke = this._strokeColor; - let vert = new TiltGL.VertexBuffer(gl, [aV0[0], aV0[1], aV0[2] || 0, - aV1[0], aV1[1], aV1[2] || 0, - aV2[0], aV2[1], aV2[2] || 0, - aV3[0], aV3[1], aV3[2] || 0], 3); - - // use the necessary shader and draw the vertices - this.useColorShader(vert, fill); - this.drawVertices(gl.TRIANGLE_FAN, vert.numItems); - - this.useColorShader(vert, stroke); - this.drawVertices(gl.LINE_LOOP, vert.numItems); - - TiltUtils.destroyObject(vert); - }, - - /** - * Function called when this object is destroyed. - */ - finalize: function TGLR_finalize() - { - if (this.context) { - TiltUtils.destroyObject(this._colorShader); - } - } -}; - -/** - * Creates a vertex buffer containing an array of elements. - * - * @param {Object} aContext - * a WebGL context - * @param {Array} aElementsArray - * an array of numbers (floats) - * @param {Number} aItemSize - * how many items create a block - * @param {Number} aNumItems - * optional, how many items to use from the array - */ -TiltGL.VertexBuffer = function TGL_VertexBuffer( - aContext, aElementsArray, aItemSize, aNumItems) -{ - /** - * The parent WebGL context. - */ - this._context = aContext; - - /** - * The array buffer. - */ - this._ref = null; - - /** - * Array of number components contained in the buffer. - */ - this.components = null; - - /** - * Variables defining the internal structure of the buffer. - */ - this.itemSize = 0; - this.numItems = 0; - - // if the array is specified in the constructor, initialize directly - if (aElementsArray) { - this.initBuffer(aElementsArray, aItemSize, aNumItems); - } -}; - -TiltGL.VertexBuffer.prototype = { - - /** - * Initializes buffer data to be used for drawing, using an array of floats. - * The "aNumItems" param can be specified to use only a portion of the array. - * - * @param {Array} aElementsArray - * an array of floats - * @param {Number} aItemSize - * how many items create a block - * @param {Number} aNumItems - * optional, how many items to use from the array - */ - initBuffer: function TGLVB_initBuffer(aElementsArray, aItemSize, aNumItems) - { - let gl = this._context; - - // the aNumItems parameter is optional, we can compute it if not specified - aNumItems = aNumItems || aElementsArray.length / aItemSize; - - // create the Float32Array using the elements array - this.components = new Float32Array(aElementsArray); - - // create an array buffer and bind the elements as a Float32Array - this._ref = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, this._ref); - gl.bufferData(gl.ARRAY_BUFFER, this.components, gl.STATIC_DRAW); - - // remember some properties, useful when binding the buffer to a shader - this.itemSize = aItemSize; - this.numItems = aNumItems; - }, - - /** - * Function called when this object is destroyed. - */ - finalize: function TGLVB_finalize() - { - if (this._context) { - this._context.deleteBuffer(this._ref); - } - } -}; - -/** - * Creates an index buffer containing an array of indices. - * - * @param {Object} aContext - * a WebGL context - * @param {Array} aElementsArray - * an array of unsigned integers - * @param {Number} aNumItems - * optional, how many items to use from the array - */ -TiltGL.IndexBuffer = function TGL_IndexBuffer( - aContext, aElementsArray, aNumItems) -{ - /** - * The parent WebGL context. - */ - this._context = aContext; - - /** - * The element array buffer. - */ - this._ref = null; - - /** - * Array of number components contained in the buffer. - */ - this.components = null; - - /** - * Variables defining the internal structure of the buffer. - */ - this.itemSize = 0; - this.numItems = 0; - - // if the array is specified in the constructor, initialize directly - if (aElementsArray) { - this.initBuffer(aElementsArray, aNumItems); - } -}; - -TiltGL.IndexBuffer.prototype = { - - /** - * Initializes a buffer of vertex indices, using an array of unsigned ints. - * The item size will automatically default to 1, and the "numItems" will be - * equal to the number of items in the array if not specified. - * - * @param {Array} aElementsArray - * an array of numbers (unsigned integers) - * @param {Number} aNumItems - * optional, how many items to use from the array - */ - initBuffer: function TGLIB_initBuffer(aElementsArray, aNumItems) - { - let gl = this._context; - - // the aNumItems parameter is optional, we can compute it if not specified - aNumItems = aNumItems || aElementsArray.length; - - // create the Uint16Array using the elements array - this.components = new Uint16Array(aElementsArray); - - // create an array buffer and bind the elements as a Uint16Array - this._ref = gl.createBuffer(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ref); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.components, gl.STATIC_DRAW); - - // remember some properties, useful when binding the buffer to a shader - this.itemSize = 1; - this.numItems = aNumItems; - }, - - /** - * Function called when this object is destroyed. - */ - finalize: function TGLIB_finalize() - { - if (this._context) { - this._context.deleteBuffer(this._ref); - } - } -}; - -/** - * A program is composed of a vertex and a fragment shader. - * - * @param {Object} aProperties - * optional, an object containing the following properties: - * {String} vs: the vertex shader source code - * {String} fs: the fragment shader source code - * {Array} attributes: an array of attributes as strings - * {Array} uniforms: an array of uniforms as strings - */ -TiltGL.Program = function(aContext, aProperties) -{ - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - /** - * The parent WebGL context. - */ - this._context = aContext; - - /** - * A reference to the actual GLSL program. - */ - this._ref = null; - - /** - * Each program has an unique id assigned. - */ - this._id = -1; - - /** - * Two arrays: an attributes array, containing all the cached attributes - * and a uniforms array, containing all the cached uniforms. - */ - this._attributes = null; - this._uniforms = null; - - // if the sources are specified in the constructor, initialize directly - if (aProperties.vs && aProperties.fs) { - this.initProgram(aProperties); - } -}; - -TiltGL.Program.prototype = { - - /** - * Initializes a shader program, using specified source code as strings. - * - * @param {Object} aProperties - * an object containing the following properties: - * {String} vs: the vertex shader source code - * {String} fs: the fragment shader source code - * {Array} attributes: an array of attributes as strings - * {Array} uniforms: an array of uniforms as strings - */ - initProgram: function TGLP_initProgram(aProperties) - { - this._ref = TiltGL.ProgramUtils.create(this._context, aProperties); - - // cache for faster access - this._id = this._ref.id; - this._attributes = this._ref.attributes; - this._uniforms = this._ref.uniforms; - - // cleanup - delete this._ref.id; - delete this._ref.attributes; - delete this._ref.uniforms; - }, - - /** - * Uses the shader program as current one for the WebGL context; it also - * enables vertex attributes necessary to enable when using this program. - * This method also does some useful caching, as the function "useProgram" - * could take quite a lot of time. - */ - use: function TGLP_use() - { - let id = this._id; - let utils = TiltGL.ProgramUtils; - - // check if the program wasn't already active - if (utils._activeProgram !== id) { - utils._activeProgram = id; - - // use the the program if it wasn't already set - this._context.useProgram(this._ref); - this.cleanupVertexAttrib(); - - // enable any necessary vertex attributes using the cache - for (let key in this._attributes) { - this._context.enableVertexAttribArray(this._attributes[key]); - utils._enabledAttributes.push(this._attributes[key]); - } - } - }, - - /** - * Disables all currently enabled vertex attribute arrays. - */ - cleanupVertexAttrib: function TGLP_cleanupVertexAttrib() - { - let utils = TiltGL.ProgramUtils; - - for (let attribute of utils._enabledAttributes) { - this._context.disableVertexAttribArray(attribute); - } - utils._enabledAttributes = []; - }, - - /** - * Binds a vertex buffer as an array buffer for a specific shader attribute. - * - * @param {String} aAtribute - * the attribute name obtained from the shader - * @param {Float32Array} aBuffer - * the buffer to be bound - */ - bindVertexBuffer: function TGLP_bindVertexBuffer(aAtribute, aBuffer) - { - // get the cached attribute value from the shader - let gl = this._context; - let attr = this._attributes[aAtribute]; - let size = aBuffer.itemSize; - - gl.bindBuffer(gl.ARRAY_BUFFER, aBuffer._ref); - gl.vertexAttribPointer(attr, size, gl.FLOAT, false, 0, 0); - }, - - /** - * Binds a uniform matrix to the current shader. - * - * @param {String} aUniform - * the uniform name to bind the variable to - * @param {Float32Array} m - * the matrix to be bound - */ - bindUniformMatrix: function TGLP_bindUniformMatrix(aUniform, m) - { - this._context.uniformMatrix4fv(this._uniforms[aUniform], false, m); - }, - - /** - * Binds a uniform vector of 4 elements to the current shader. - * - * @param {String} aUniform - * the uniform name to bind the variable to - * @param {Float32Array} v - * the vector to be bound - */ - bindUniformVec4: function TGLP_bindUniformVec4(aUniform, v) - { - this._context.uniform4fv(this._uniforms[aUniform], v); - }, - - /** - * Binds a simple float element to the current shader. - * - * @param {String} aUniform - * the uniform name to bind the variable to - * @param {Number} v - * the variable to be bound - */ - bindUniformFloat: function TGLP_bindUniformFloat(aUniform, f) - { - this._context.uniform1f(this._uniforms[aUniform], f); - }, - - /** - * Binds a uniform texture for a sampler to the current shader. - * - * @param {String} aSampler - * the sampler name to bind the texture to - * @param {TiltGL.Texture} aTexture - * the texture to be bound - */ - bindTexture: function TGLP_bindTexture(aSampler, aTexture) - { - let gl = this._context; - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, aTexture._ref); - gl.uniform1i(this._uniforms[aSampler], 0); - }, - - /** - * Function called when this object is destroyed. - */ - finalize: function TGLP_finalize() - { - if (this._context) { - this._context.useProgram(null); - this._context.deleteProgram(this._ref); - } - } -}; - -/** - * Utility functions for handling GLSL shaders and programs. - */ -TiltGL.ProgramUtils = { - - /** - * Initializes a shader program, using specified source code as strings, - * returning the newly created shader program, by compiling and linking the - * vertex and fragment shader. - * - * @param {Object} aContext - * a WebGL context - * @param {Object} aProperties - * an object containing the following properties: - * {String} vs: the vertex shader source code - * {String} fs: the fragment shader source code - * {Array} attributes: an array of attributes as strings - * {Array} uniforms: an array of uniforms as strings - */ - create: function TGLPU_create(aContext, aProperties) - { - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - // compile the two shaders - let vertShader = this.compile(aContext, aProperties.vs, "vertex"); - let fragShader = this.compile(aContext, aProperties.fs, "fragment"); - let program = this.link(aContext, vertShader, fragShader); - - aContext.deleteShader(vertShader); - aContext.deleteShader(fragShader); - - return this.cache(aContext, aProperties, program); - }, - - /** - * Compiles a shader source of a specific type, either vertex or fragment. - * - * @param {Object} aContext - * a WebGL context - * @param {String} aShaderSource - * the source code for the shader - * @param {String} aShaderType - * the shader type ("vertex" or "fragment") - * - * @return {WebGLShader} the compiled shader - */ - compile: function TGLPU_compile(aContext, aShaderSource, aShaderType) - { - let gl = aContext, shader, status; - - // make sure the shader source is valid - if ("string" !== typeof aShaderSource || aShaderSource.length < 1) { - TiltUtils.Output.error( - TiltUtils.L10n.get("compileShader.source.error")); - return null; - } - - // also make sure the necessary shader mime type is valid - if (aShaderType === "vertex") { - shader = gl.createShader(gl.VERTEX_SHADER); - } else if (aShaderType === "fragment") { - shader = gl.createShader(gl.FRAGMENT_SHADER); - } else { - TiltUtils.Output.error( - TiltUtils.L10n.format("compileShader.type.error", [aShaderSource])); - return null; - } - - // set the shader source and compile it - gl.shaderSource(shader, aShaderSource); - gl.compileShader(shader); - - // remember the shader source (useful for debugging and caching) - shader.src = aShaderSource; - - // verify the compile status; if something went wrong, log the error - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - status = gl.getShaderInfoLog(shader); - - TiltUtils.Output.error( - TiltUtils.L10n.format("compileShader.compile.error", [status])); - return null; - } - - // return the newly compiled shader from the specified source - return shader; - }, - - /** - * Links two compiled vertex or fragment shaders together to form a program. - * - * @param {Object} aContext - * a WebGL context - * @param {WebGLShader} aVertShader - * the compiled vertex shader - * @param {WebGLShader} aFragShader - * the compiled fragment shader - * - * @return {WebGLProgram} the newly created and linked shader program - */ - link: function TGLPU_link(aContext, aVertShader, aFragShader) - { - let gl = aContext, program, status; - - // create a program and attach the compiled vertex and fragment shaders - program = gl.createProgram(); - - // attach the vertex and fragment shaders to the program - gl.attachShader(program, aVertShader); - gl.attachShader(program, aFragShader); - gl.linkProgram(program); - - // verify the link status; if something went wrong, log the error - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - status = gl.getProgramInfoLog(program); - - TiltUtils.Output.error( - TiltUtils.L10n.format("linkProgram.error", [status])); - return null; - } - - // generate an id for the program - program.id = this._count++; - - return program; - }, - - /** - * Caches shader attributes and uniforms as properties for a program object. - * - * @param {Object} aContext - * a WebGL context - * @param {Object} aProperties - * an object containing the following properties: - * {Array} attributes: optional, an array of attributes as strings - * {Array} uniforms: optional, an array of uniforms as strings - * @param {WebGLProgram} aProgram - * the shader program used for caching - * - * @return {WebGLProgram} the same program - */ - cache: function TGLPU_cache(aContext, aProperties, aProgram) - { - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - // make sure the attributes and uniforms cache objects are created - aProgram.attributes = {}; - aProgram.uniforms = {}; - - Object.defineProperty(aProgram.attributes, "length", - { value: 0, writable: true, enumerable: false, configurable: true }); - - Object.defineProperty(aProgram.uniforms, "length", - { value: 0, writable: true, enumerable: false, configurable: true }); - - - let attr = aProperties.attributes; - let unif = aProperties.uniforms; - - if (attr) { - for (let i = 0, len = attr.length; i < len; i++) { - // try to get a shader attribute from the program - let param = attr[i]; - let loc = aContext.getAttribLocation(aProgram, param); - - if ("number" === typeof loc && loc > -1) { - // if we get an attribute location, store it - // bind the new parameter only if it was not already defined - if (aProgram.attributes[param] === undefined) { - aProgram.attributes[param] = loc; - aProgram.attributes.length++; - } - } - } - } - - if (unif) { - for (let i = 0, len = unif.length; i < len; i++) { - // try to get a shader uniform from the program - let param = unif[i]; - let loc = aContext.getUniformLocation(aProgram, param); - - if ("object" === typeof loc && loc) { - // if we get a uniform object, store it - // bind the new parameter only if it was not already defined - if (aProgram.uniforms[param] === undefined) { - aProgram.uniforms[param] = loc; - aProgram.uniforms.length++; - } - } - } - } - - return aProgram; - }, - - /** - * The total number of programs created. - */ - _count: 0, - - /** - * Represents the current active shader, identified by an id. - */ - _activeProgram: -1, - - /** - * Represents the current enabled attributes. - */ - _enabledAttributes: [] -}; - -/** - * This constructor creates a texture from an Image. - * - * @param {Object} aContext - * a WebGL context - * @param {Object} aProperties - * optional, an object containing the following properties: - * {Image} source: the source image for the texture - * {String} format: the format of the texture ("RGB" or "RGBA") - * {String} fill: optional, color to fill the transparent bits - * {String} stroke: optional, color to draw an outline - * {Number} strokeWeight: optional, the width of the outline - * {String} minFilter: either "nearest" or "linear" - * {String} magFilter: either "nearest" or "linear" - * {String} wrapS: either "repeat" or "clamp" - * {String} wrapT: either "repeat" or "clamp" - * {Boolean} mipmap: true if should generate mipmap - */ -TiltGL.Texture = function(aContext, aProperties) -{ - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - /** - * The parent WebGL context. - */ - this._context = aContext; - - /** - * A reference to the WebGL texture object. - */ - this._ref = null; - - /** - * Each texture has an unique id assigned. - */ - this._id = -1; - - /** - * Variables specifying the width and height of the texture. - * If these values are less than 0, the texture hasn't loaded yet. - */ - this.width = -1; - this.height = -1; - - /** - * Specifies if the texture has loaded or not. - */ - this.loaded = false; - - // if the image is specified in the constructor, initialize directly - if ("object" === typeof aProperties.source) { - this.initTexture(aProperties); - } else { - TiltUtils.Output.error( - TiltUtils.L10n.get("initTexture.source.error")); - } -}; - -TiltGL.Texture.prototype = { - - /** - * Initializes a texture from a pre-existing image or canvas. - * - * @param {Image} aImage - * the source image or canvas - * @param {Object} aProperties - * an object containing the following properties: - * {Image} source: the source image for the texture - * {String} format: the format of the texture ("RGB" or "RGBA") - * {String} fill: optional, color to fill the transparent bits - * {String} stroke: optional, color to draw an outline - * {Number} strokeWeight: optional, the width of the outline - * {String} minFilter: either "nearest" or "linear" - * {String} magFilter: either "nearest" or "linear" - * {String} wrapS: either "repeat" or "clamp" - * {String} wrapT: either "repeat" or "clamp" - * {Boolean} mipmap: true if should generate mipmap - */ - initTexture: function TGLT_initTexture(aProperties) - { - this._ref = TiltGL.TextureUtils.create(this._context, aProperties); - - // cache for faster access - this._id = this._ref.id; - this.width = this._ref.width; - this.height = this._ref.height; - this.loaded = true; - - // cleanup - delete this._ref.id; - delete this._ref.width; - delete this._ref.height; - delete this.onload; - }, - - /** - * Function called when this object is destroyed. - */ - finalize: function TGLT_finalize() - { - if (this._context) { - this._context.deleteTexture(this._ref); - } - } -}; - -/** - * Utility functions for creating and manipulating textures. - */ -TiltGL.TextureUtils = { - - /** - * Initializes a texture from a pre-existing image or canvas. - * - * @param {Object} aContext - * a WebGL context - * @param {Image} aImage - * the source image or canvas - * @param {Object} aProperties - * an object containing some of the following properties: - * {Image} source: the source image for the texture - * {String} format: the format of the texture ("RGB" or "RGBA") - * {String} fill: optional, color to fill the transparent bits - * {String} stroke: optional, color to draw an outline - * {Number} strokeWeight: optional, the width of the outline - * {String} minFilter: either "nearest" or "linear" - * {String} magFilter: either "nearest" or "linear" - * {String} wrapS: either "repeat" or "clamp" - * {String} wrapT: either "repeat" or "clamp" - * {Boolean} mipmap: true if should generate mipmap - * - * @return {WebGLTexture} the created texture - */ - create: function TGLTU_create(aContext, aProperties) - { - // make sure the properties argument is an object - aProperties = aProperties || {}; - - if (!aProperties.source) { - return null; - } - - let gl = aContext; - let width = aProperties.source.width; - let height = aProperties.source.height; - let format = gl[aProperties.format || "RGB"]; - - // make sure the image is power of two before binding to a texture - let source = this.resizeImageToPowerOfTwo(aProperties); - - // first, create the texture to hold the image data - let texture = gl.createTexture(); - - // attach the image data to the newly create texture - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texImage2D(gl.TEXTURE_2D, 0, format, format, gl.UNSIGNED_BYTE, source); - this.setTextureParams(gl, aProperties); - - // do some cleanup - gl.bindTexture(gl.TEXTURE_2D, null); - - // remember the width and the height - texture.width = width; - texture.height = height; - - // generate an id for the texture - texture.id = this._count++; - - return texture; - }, - - /** - * Sets texture parameters for the current texture binding. - * Optionally, you can also (re)set the current texture binding manually. - * - * @param {Object} aContext - * a WebGL context - * @param {Object} aProperties - * an object containing the texture properties - */ - setTextureParams: function TGLTU_setTextureParams(aContext, aProperties) - { - // make sure the properties argument is an object - aProperties = aProperties || {}; - - let gl = aContext; - let minFilter = gl.TEXTURE_MIN_FILTER; - let magFilter = gl.TEXTURE_MAG_FILTER; - let wrapS = gl.TEXTURE_WRAP_S; - let wrapT = gl.TEXTURE_WRAP_T; - - // bind a new texture if necessary - if (aProperties.texture) { - gl.bindTexture(gl.TEXTURE_2D, aProperties.texture.ref); - } - - // set the minification filter - if ("nearest" === aProperties.minFilter) { - gl.texParameteri(gl.TEXTURE_2D, minFilter, gl.NEAREST); - } else if ("linear" === aProperties.minFilter && aProperties.mipmap) { - gl.texParameteri(gl.TEXTURE_2D, minFilter, gl.LINEAR_MIPMAP_LINEAR); - } else { - gl.texParameteri(gl.TEXTURE_2D, minFilter, gl.LINEAR); - } - - // set the magnification filter - if ("nearest" === aProperties.magFilter) { - gl.texParameteri(gl.TEXTURE_2D, magFilter, gl.NEAREST); - } else { - gl.texParameteri(gl.TEXTURE_2D, magFilter, gl.LINEAR); - } - - // set the wrapping on the x-axis for the texture - if ("repeat" === aProperties.wrapS) { - gl.texParameteri(gl.TEXTURE_2D, wrapS, gl.REPEAT); - } else { - gl.texParameteri(gl.TEXTURE_2D, wrapS, gl.CLAMP_TO_EDGE); - } - - // set the wrapping on the y-axis for the texture - if ("repeat" === aProperties.wrapT) { - gl.texParameteri(gl.TEXTURE_2D, wrapT, gl.REPEAT); - } else { - gl.texParameteri(gl.TEXTURE_2D, wrapT, gl.CLAMP_TO_EDGE); - } - - // generate mipmap if necessary - if (aProperties.mipmap) { - gl.generateMipmap(gl.TEXTURE_2D); - } - }, - - /** - * This shim renders a content window to a canvas element, but clamps the - * maximum width and height of the canvas to the WebGL MAX_TEXTURE_SIZE. - * - * @param {Window} aContentWindow - * the content window to get a texture from - * @param {Number} aMaxImageSize - * the maximum image size to be used - * - * @return {Image} the new content window image - */ - createContentImage: function TGLTU_createContentImage( - aContentWindow, aMaxImageSize) - { - // calculate the total width and height of the content page - let size = TiltUtils.DOM.getContentWindowDimensions(aContentWindow); - - // use a custom canvas element and a 2d context to draw the window - let canvas = TiltUtils.DOM.initCanvas(null); - canvas.width = TiltMath.clamp(size.width, 0, aMaxImageSize); - canvas.height = TiltMath.clamp(size.height, 0, aMaxImageSize); - - // use the 2d context.drawWindow() magic - let ctx = canvas.getContext("2d"); - ctx.drawWindow(aContentWindow, 0, 0, canvas.width, canvas.height, "#fff"); - - return canvas; - }, - - /** - * Scales an image's width and height to next power of two. - * If the image already has power of two sizes, it is immediately returned, - * otherwise, a new image is created. - * - * @param {Image} aImage - * the image to be scaled - * @param {Object} aProperties - * an object containing the following properties: - * {Image} source: the source image to resize - * {Boolean} resize: true to resize the image if it has npot dimensions - * {String} fill: optional, color to fill the transparent bits - * {String} stroke: optional, color to draw an image outline - * {Number} strokeWeight: optional, the width of the outline - * - * @return {Image} the resized image - */ - resizeImageToPowerOfTwo: function TGLTU_resizeImageToPowerOfTwo(aProperties) - { - // make sure the properties argument is an object - aProperties = aProperties || {}; - - if (!aProperties.source) { - return null; - } - - let isPowerOfTwoWidth = TiltMath.isPowerOfTwo(aProperties.source.width); - let isPowerOfTwoHeight = TiltMath.isPowerOfTwo(aProperties.source.height); - - // first check if the image is not already power of two - if (!aProperties.resize || (isPowerOfTwoWidth && isPowerOfTwoHeight)) { - return aProperties.source; - } - - // calculate the power of two dimensions for the npot image - let width = TiltMath.nextPowerOfTwo(aProperties.source.width); - let height = TiltMath.nextPowerOfTwo(aProperties.source.height); - - // create a canvas, then we will use a 2d context to scale the image - let canvas = TiltUtils.DOM.initCanvas(null, { - width: width, - height: height - }); - - let ctx = canvas.getContext("2d"); - - // optional fill (useful when handling transparent images) - if (aProperties.fill) { - ctx.fillStyle = aProperties.fill; - ctx.fillRect(0, 0, width, height); - } - - // draw the image with power of two dimensions - ctx.drawImage(aProperties.source, 0, 0, width, height); - - // optional stroke (useful when creating textures for edges) - if (aProperties.stroke) { - ctx.strokeStyle = aProperties.stroke; - ctx.lineWidth = aProperties.strokeWeight; - ctx.strokeRect(0, 0, width, height); - } - - return canvas; - }, - - /** - * The total number of textures created. - */ - _count: 0 -}; - -/** - * A color shader. The only useful thing it does is set the gl_FragColor. - * - * @param {Attribute} vertexPosition: the vertex position - * @param {Uniform} mvMatrix: the model view matrix - * @param {Uniform} projMatrix: the projection matrix - * @param {Uniform} color: the color to set the gl_FragColor to - */ -TiltGL.ColorShader = { - - /** - * Vertex shader. - */ - vs: [ - "attribute vec3 vertexPosition;", - - "uniform mat4 mvMatrix;", - "uniform mat4 projMatrix;", - - "void main() {", - " gl_Position = projMatrix * mvMatrix * vec4(vertexPosition, 1.0);", - "}" - ].join("\n"), - - /** - * Fragment shader. - */ - fs: [ - "#ifdef GL_ES", - "precision lowp float;", - "#endif", - - "uniform vec4 fill;", - - "void main() {", - " gl_FragColor = fill;", - "}" - ].join("\n") -}; - -TiltGL.isWebGLForceEnabled = function TGL_isWebGLForceEnabled() -{ - return Services.prefs.getBoolPref("webgl.force-enabled"); -}; - -/** - * Tests if the WebGL OpenGL or Angle renderer is available using the - * GfxInfo service. - * - * @return {Boolean} true if WebGL is available - */ -TiltGL.isWebGLSupported = function TGL_isWebGLSupported() -{ - let supported = false; - - try { - let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo); - let angle = gfxInfo.FEATURE_WEBGL_ANGLE; - let opengl = gfxInfo.FEATURE_WEBGL_OPENGL; - - // if either the Angle or OpenGL renderers are available, WebGL should work - supported = gfxInfo.getFeatureStatus(angle) === gfxInfo.FEATURE_STATUS_OK || - gfxInfo.getFeatureStatus(opengl) === gfxInfo.FEATURE_STATUS_OK; - } catch(e) { - if (e && e.message) { TiltUtils.Output.error(e.message); } - return false; - } - return supported; -}; - -/** - * Helper function to create a 3D context. - * - * @param {HTMLCanvasElement} aCanvas - * the canvas to get the WebGL context from - * @param {Object} aFlags - * optional, flags used for initialization - * - * @return {Object} the WebGL context, or null if anything failed - */ -TiltGL.create3DContext = function TGL_create3DContext(aCanvas, aFlags) -{ - TiltGL.clearCache(); - - // try to get a valid context from an existing canvas - let context = null; - - try { - context = aCanvas.getContext(WEBGL_CONTEXT_NAME, aFlags); - } catch(e) { - if (e && e.message) { TiltUtils.Output.error(e.message); } - return null; - } - return context; -}; - -/** - * Clears the cache and sets all the variables to default. - */ -TiltGL.clearCache = function TGL_clearCache() -{ - TiltGL.ProgramUtils._activeProgram = -1; - TiltGL.ProgramUtils._enabledAttributes = []; -}; diff --git a/devtools/client/tilt/tilt-math.js b/devtools/client/tilt/tilt-math.js deleted file mode 100644 index eb53f946a8d7..000000000000 --- a/devtools/client/tilt/tilt-math.js +++ /dev/null @@ -1,2322 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {Cu} = require("chrome"); - -var TiltUtils = require("devtools/client/tilt/tilt-utils"); - -/** - * Module containing high performance matrix and vector operations for WebGL. - * Inspired by glMatrix, version 0.9.6, (c) 2011 Brandon Jones. - */ - -var EPSILON = 0.01; -exports.EPSILON = EPSILON; - -const PI_OVER_180 = Math.PI / 180; -const INV_PI_OVER_180 = 180 / Math.PI; -const FIFTEEN_OVER_225 = 15 / 225; -const ONE_OVER_255 = 1 / 255; - -/** - * vec3 - 3 Dimensional Vector. - */ -var vec3 = { - - /** - * Creates a new instance of a vec3 using the Float32Array type. - * Any array containing at least 3 numeric elements can serve as a vec3. - * - * @param {Array} aVec - * optional, vec3 containing values to initialize with - * - * @return {Array} a new instance of a vec3 - */ - create: function V3_create(aVec) - { - let dest = new Float32Array(3); - - if (aVec) { - vec3.set(aVec, dest); - } else { - vec3.zero(dest); - } - return dest; - }, - - /** - * Copies the values of one vec3 to another. - * - * @param {Array} aVec - * vec3 containing values to copy - * @param {Array} aDest - * vec3 receiving copied values - * - * @return {Array} the destination vec3 receiving copied values - */ - set: function V3_set(aVec, aDest) - { - aDest[0] = aVec[0]; - aDest[1] = aVec[1]; - aDest[2] = aVec[2] || 0; - return aDest; - }, - - /** - * Sets a vec3 to an zero vector. - * - * @param {Array} aDest - * vec3 to set - * - * @return {Array} the same vector - */ - zero: function V3_zero(aDest) - { - aDest[0] = 0; - aDest[1] = 0; - aDest[2] = 0; - return aDest; - }, - - /** - * Performs a vector addition. - * - * @param {Array} aVec - * vec3, first operand - * @param {Array} aVec2 - * vec3, second operand - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - add: function V3_add(aVec, aVec2, aDest) - { - if (!aDest) { - aDest = aVec; - } - - aDest[0] = aVec[0] + aVec2[0]; - aDest[1] = aVec[1] + aVec2[1]; - aDest[2] = aVec[2] + aVec2[2]; - return aDest; - }, - - /** - * Performs a vector subtraction. - * - * @param {Array} aVec - * vec3, first operand - * @param {Array} aVec2 - * vec3, second operand - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - subtract: function V3_subtract(aVec, aVec2, aDest) - { - if (!aDest) { - aDest = aVec; - } - - aDest[0] = aVec[0] - aVec2[0]; - aDest[1] = aVec[1] - aVec2[1]; - aDest[2] = aVec[2] - aVec2[2]; - return aDest; - }, - - /** - * Negates the components of a vec3. - * - * @param {Array} aVec - * vec3 to negate - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - negate: function V3_negate(aVec, aDest) - { - if (!aDest) { - aDest = aVec; - } - - aDest[0] = -aVec[0]; - aDest[1] = -aVec[1]; - aDest[2] = -aVec[2]; - return aDest; - }, - - /** - * Multiplies the components of a vec3 by a scalar value. - * - * @param {Array} aVec - * vec3 to scale - * @param {Number} aVal - * numeric value to scale by - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - scale: function V3_scale(aVec, aVal, aDest) - { - if (!aDest) { - aDest = aVec; - } - - aDest[0] = aVec[0] * aVal; - aDest[1] = aVec[1] * aVal; - aDest[2] = aVec[2] * aVal; - return aDest; - }, - - /** - * Generates a unit vector of the same direction as the provided vec3. - * If vector length is 0, returns [0, 0, 0]. - * - * @param {Array} aVec - * vec3 to normalize - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - normalize: function V3_normalize(aVec, aDest) - { - if (!aDest) { - aDest = aVec; - } - - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - let len = Math.sqrt(x * x + y * y + z * z); - - if (Math.abs(len) < EPSILON) { - aDest[0] = 0; - aDest[1] = 0; - aDest[2] = 0; - return aDest; - } - - len = 1 / len; - aDest[0] = x * len; - aDest[1] = y * len; - aDest[2] = z * len; - return aDest; - }, - - /** - * Generates the cross product of two vectors. - * - * @param {Array} aVec - * vec3, first operand - * @param {Array} aVec2 - * vec3, second operand - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - cross: function V3_cross(aVec, aVec2, aDest) - { - if (!aDest) { - aDest = aVec; - } - - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - let x2 = aVec2[0]; - let y2 = aVec2[1]; - let z2 = aVec2[2]; - - aDest[0] = y * z2 - z * y2; - aDest[1] = z * x2 - x * z2; - aDest[2] = x * y2 - y * x2; - return aDest; - }, - - /** - * Caclulate the dot product of two vectors. - * - * @param {Array} aVec - * vec3, first operand - * @param {Array} aVec2 - * vec3, second operand - * - * @return {Array} dot product of the first and second operand - */ - dot: function V3_dot(aVec, aVec2) - { - return aVec[0] * aVec2[0] + aVec[1] * aVec2[1] + aVec[2] * aVec2[2]; - }, - - /** - * Caclulate the length of a vec3. - * - * @param {Array} aVec - * vec3 to calculate length of - * - * @return {Array} length of the vec3 - */ - length: function V3_length(aVec) - { - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - - return Math.sqrt(x * x + y * y + z * z); - }, - - /** - * Generates a unit vector pointing from one vector to another. - * - * @param {Array} aVec - * origin vec3 - * @param {Array} aVec2 - * vec3 to point to - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - direction: function V3_direction(aVec, aVec2, aDest) - { - if (!aDest) { - aDest = aVec; - } - - let x = aVec[0] - aVec2[0]; - let y = aVec[1] - aVec2[1]; - let z = aVec[2] - aVec2[2]; - let len = Math.sqrt(x * x + y * y + z * z); - - if (Math.abs(len) < EPSILON) { - aDest[0] = 0; - aDest[1] = 0; - aDest[2] = 0; - return aDest; - } - - len = 1 / len; - aDest[0] = x * len; - aDest[1] = y * len; - aDest[2] = z * len; - return aDest; - }, - - /** - * Performs a linear interpolation between two vec3. - * - * @param {Array} aVec - * first vector - * @param {Array} aVec2 - * second vector - * @param {Number} aLerp - * interpolation amount between the two inputs - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, first operand otherwise - */ - lerp: function V3_lerp(aVec, aVec2, aLerp, aDest) - { - if (!aDest) { - aDest = aVec; - } - - aDest[0] = aVec[0] + aLerp * (aVec2[0] - aVec[0]); - aDest[1] = aVec[1] + aLerp * (aVec2[1] - aVec[1]); - aDest[2] = aVec[2] + aLerp * (aVec2[2] - aVec[2]); - return aDest; - }, - - /** - * Projects a 3D point on a 2D screen plane. - * - * @param {Array} aP - * the [x, y, z] coordinates of the point to project - * @param {Array} aViewport - * the viewport [x, y, width, height] coordinates - * @param {Array} aMvMatrix - * the model view matrix - * @param {Array} aProjMatrix - * the projection matrix - * @param {Array} aDest - * optional parameter, the array to write the values to - * - * @return {Array} the projected coordinates - */ - project: function V3_project(aP, aViewport, aMvMatrix, aProjMatrix, aDest) - { - /*jshint undef: false */ - - let mvpMatrix = new Float32Array(16); - let coordinates = new Float32Array(4); - - // compute the perspective * model view matrix - mat4.multiply(aProjMatrix, aMvMatrix, mvpMatrix); - - // now transform that vector into homogenous coordinates - coordinates[0] = aP[0]; - coordinates[1] = aP[1]; - coordinates[2] = aP[2]; - coordinates[3] = 1; - mat4.multiplyVec4(mvpMatrix, coordinates); - - // transform the homogenous coordinates into screen space - coordinates[0] /= coordinates[3]; - coordinates[0] *= aViewport[2] * 0.5; - coordinates[0] += aViewport[2] * 0.5; - coordinates[1] /= coordinates[3]; - coordinates[1] *= -aViewport[3] * 0.5; - coordinates[1] += aViewport[3] * 0.5; - coordinates[2] = 0; - - if (!aDest) { - vec3.set(coordinates, aP); - } else { - vec3.set(coordinates, aDest); - } - return coordinates; - }, - - /** - * Unprojects a 2D point to 3D space. - * - * @param {Array} aP - * the [x, y, z] coordinates of the point to unproject; - * the z value should range between 0 and 1, as clipping plane - * @param {Array} aViewport - * the viewport [x, y, width, height] coordinates - * @param {Array} aMvMatrix - * the model view matrix - * @param {Array} aProjMatrix - * the projection matrix - * @param {Array} aDest - * optional parameter, the array to write the values to - * - * @return {Array} the unprojected coordinates - */ - unproject: function V3_unproject( - aP, aViewport, aMvMatrix, aProjMatrix, aDest) - { - /*jshint undef: false */ - - let mvpMatrix = new Float32Array(16); - let coordinates = new Float32Array(4); - - // compute the inverse of the perspective * model view matrix - mat4.multiply(aProjMatrix, aMvMatrix, mvpMatrix); - mat4.inverse(mvpMatrix); - - // transformation of normalized coordinates (-1 to 1) - coordinates[0] = +((aP[0] - aViewport[0]) / aViewport[2] * 2 - 1); - coordinates[1] = -((aP[1] - aViewport[1]) / aViewport[3] * 2 - 1); - coordinates[2] = 2 * aP[2] - 1; - coordinates[3] = 1; - - // now transform that vector into space coordinates - mat4.multiplyVec4(mvpMatrix, coordinates); - - // invert to normalize x, y, and z values - coordinates[3] = 1 / coordinates[3]; - coordinates[0] *= coordinates[3]; - coordinates[1] *= coordinates[3]; - coordinates[2] *= coordinates[3]; - - if (!aDest) { - vec3.set(coordinates, aP); - } else { - vec3.set(coordinates, aDest); - } - return coordinates; - }, - - /** - * Create a ray between two points using the current model view & projection - * matrices. This is useful when creating a ray destined for 3D picking. - * - * @param {Array} aP0 - * the [x, y, z] coordinates of the first point - * @param {Array} aP1 - * the [x, y, z] coordinates of the second point - * @param {Array} aViewport - * the viewport [x, y, width, height] coordinates - * @param {Array} aMvMatrix - * the model view matrix - * @param {Array} aProjMatrix - * the projection matrix - * - * @return {Object} a ray object containing the direction vector between - * the two unprojected points, the position and the lookAt - */ - createRay: function V3_createRay(aP0, aP1, aViewport, aMvMatrix, aProjMatrix) - { - // unproject the two points - vec3.unproject(aP0, aViewport, aMvMatrix, aProjMatrix, aP0); - vec3.unproject(aP1, aViewport, aMvMatrix, aProjMatrix, aP1); - - return { - origin: aP0, - direction: vec3.normalize(vec3.subtract(aP1, aP0)) - }; - }, - - /** - * Returns a string representation of a vector. - * - * @param {Array} aVec - * vec3 to represent as a string - * - * @return {String} representation of the vector - */ - str: function V3_str(aVec) - { - return '[' + aVec[0] + ", " + aVec[1] + ", " + aVec[2] + ']'; - } -}; - -exports.vec3 = vec3; - -/** - * mat3 - 3x3 Matrix. - */ -var mat3 = { - - /** - * Creates a new instance of a mat3 using the Float32Array array type. - * Any array containing at least 9 numeric elements can serve as a mat3. - * - * @param {Array} aMat - * optional, mat3 containing values to initialize with - * - * @return {Array} a new instance of a mat3 - */ - create: function M3_create(aMat) - { - let dest = new Float32Array(9); - - if (aMat) { - mat3.set(aMat, dest); - } else { - mat3.identity(dest); - } - return dest; - }, - - /** - * Copies the values of one mat3 to another. - * - * @param {Array} aMat - * mat3 containing values to copy - * @param {Array} aDest - * mat3 receiving copied values - * - * @return {Array} the destination mat3 receiving copied values - */ - set: function M3_set(aMat, aDest) - { - aDest[0] = aMat[0]; - aDest[1] = aMat[1]; - aDest[2] = aMat[2]; - aDest[3] = aMat[3]; - aDest[4] = aMat[4]; - aDest[5] = aMat[5]; - aDest[6] = aMat[6]; - aDest[7] = aMat[7]; - aDest[8] = aMat[8]; - return aDest; - }, - - /** - * Sets a mat3 to an identity matrix. - * - * @param {Array} aDest - * mat3 to set - * - * @return {Array} the same matrix - */ - identity: function M3_identity(aDest) - { - aDest[0] = 1; - aDest[1] = 0; - aDest[2] = 0; - aDest[3] = 0; - aDest[4] = 1; - aDest[5] = 0; - aDest[6] = 0; - aDest[7] = 0; - aDest[8] = 1; - return aDest; - }, - - /** - * Transposes a mat3 (flips the values over the diagonal). - * - * @param {Array} aMat - * mat3 to transpose - * @param {Array} aDest - * optional, mat3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat3 if specified, first operand otherwise - */ - transpose: function M3_transpose(aMat, aDest) - { - if (!aDest || aMat === aDest) { - let a01 = aMat[1]; - let a02 = aMat[2]; - let a12 = aMat[5]; - - aMat[1] = aMat[3]; - aMat[2] = aMat[6]; - aMat[3] = a01; - aMat[5] = aMat[7]; - aMat[6] = a02; - aMat[7] = a12; - return aMat; - } - - aDest[0] = aMat[0]; - aDest[1] = aMat[3]; - aDest[2] = aMat[6]; - aDest[3] = aMat[1]; - aDest[4] = aMat[4]; - aDest[5] = aMat[7]; - aDest[6] = aMat[2]; - aDest[7] = aMat[5]; - aDest[8] = aMat[8]; - return aDest; - }, - - /** - * Copies the elements of a mat3 into the upper 3x3 elements of a mat4. - * - * @param {Array} aMat - * mat3 containing values to copy - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat3 if specified, first operand otherwise - */ - toMat4: function M3_toMat4(aMat, aDest) - { - if (!aDest) { - aDest = new Float32Array(16); - } - - aDest[0] = aMat[0]; - aDest[1] = aMat[1]; - aDest[2] = aMat[2]; - aDest[3] = 0; - aDest[4] = aMat[3]; - aDest[5] = aMat[4]; - aDest[6] = aMat[5]; - aDest[7] = 0; - aDest[8] = aMat[6]; - aDest[9] = aMat[7]; - aDest[10] = aMat[8]; - aDest[11] = 0; - aDest[12] = 0; - aDest[13] = 0; - aDest[14] = 0; - aDest[15] = 1; - return aDest; - }, - - /** - * Returns a string representation of a 3x3 matrix. - * - * @param {Array} aMat - * mat3 to represent as a string - * - * @return {String} representation of the matrix - */ - str: function M3_str(aMat) - { - return "[" + aMat[0] + ", " + aMat[1] + ", " + aMat[2] + - ", " + aMat[3] + ", " + aMat[4] + ", " + aMat[5] + - ", " + aMat[6] + ", " + aMat[7] + ", " + aMat[8] + "]"; - } -}; - -exports.mat3 = mat3; - -/** - * mat4 - 4x4 Matrix. - */ -var mat4 = { - - /** - * Creates a new instance of a mat4 using the default Float32Array type. - * Any array containing at least 16 numeric elements can serve as a mat4. - * - * @param {Array} aMat - * optional, mat4 containing values to initialize with - * - * @return {Array} a new instance of a mat4 - */ - create: function M4_create(aMat) - { - let dest = new Float32Array(16); - - if (aMat) { - mat4.set(aMat, dest); - } else { - mat4.identity(dest); - } - return dest; - }, - - /** - * Copies the values of one mat4 to another - * - * @param {Array} aMat - * mat4 containing values to copy - * @param {Array} aDest - * mat4 receiving copied values - * - * @return {Array} the destination mat4 receiving copied values - */ - set: function M4_set(aMat, aDest) - { - aDest[0] = aMat[0]; - aDest[1] = aMat[1]; - aDest[2] = aMat[2]; - aDest[3] = aMat[3]; - aDest[4] = aMat[4]; - aDest[5] = aMat[5]; - aDest[6] = aMat[6]; - aDest[7] = aMat[7]; - aDest[8] = aMat[8]; - aDest[9] = aMat[9]; - aDest[10] = aMat[10]; - aDest[11] = aMat[11]; - aDest[12] = aMat[12]; - aDest[13] = aMat[13]; - aDest[14] = aMat[14]; - aDest[15] = aMat[15]; - return aDest; - }, - - /** - * Sets a mat4 to an identity matrix. - * - * @param {Array} aDest - * mat4 to set - * - * @return {Array} the same matrix - */ - identity: function M4_identity(aDest) - { - aDest[0] = 1; - aDest[1] = 0; - aDest[2] = 0; - aDest[3] = 0; - aDest[4] = 0; - aDest[5] = 1; - aDest[6] = 0; - aDest[7] = 0; - aDest[8] = 0; - aDest[9] = 0; - aDest[10] = 1; - aDest[11] = 0; - aDest[12] = 0; - aDest[13] = 0; - aDest[14] = 0; - aDest[15] = 1; - return aDest; - }, - - /** - * Transposes a mat4 (flips the values over the diagonal). - * - * @param {Array} aMat - * mat4 to transpose - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - transpose: function M4_transpose(aMat, aDest) - { - if (!aDest || aMat === aDest) { - let a01 = aMat[1]; - let a02 = aMat[2]; - let a03 = aMat[3]; - let a12 = aMat[6]; - let a13 = aMat[7]; - let a23 = aMat[11]; - - aMat[1] = aMat[4]; - aMat[2] = aMat[8]; - aMat[3] = aMat[12]; - aMat[4] = a01; - aMat[6] = aMat[9]; - aMat[7] = aMat[13]; - aMat[8] = a02; - aMat[9] = a12; - aMat[11] = aMat[14]; - aMat[12] = a03; - aMat[13] = a13; - aMat[14] = a23; - return aMat; - } - - aDest[0] = aMat[0]; - aDest[1] = aMat[4]; - aDest[2] = aMat[8]; - aDest[3] = aMat[12]; - aDest[4] = aMat[1]; - aDest[5] = aMat[5]; - aDest[6] = aMat[9]; - aDest[7] = aMat[13]; - aDest[8] = aMat[2]; - aDest[9] = aMat[6]; - aDest[10] = aMat[10]; - aDest[11] = aMat[14]; - aDest[12] = aMat[3]; - aDest[13] = aMat[7]; - aDest[14] = aMat[11]; - aDest[15] = aMat[15]; - return aDest; - }, - - /** - * Calculate the determinant of a mat4. - * - * @param {Array} aMat - * mat4 to calculate determinant of - * - * @return {Number} determinant of the matrix - */ - determinant: function M4_determinant(mat) - { - let a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; - let a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; - let a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; - let a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; - - return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 + - a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 + - a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 + - a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 + - a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 + - a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33; - }, - - /** - * Calculate the inverse of a mat4. - * - * @param {Array} aMat - * mat4 to calculate inverse of - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - inverse: function M4_inverse(aMat, aDest) - { - if (!aDest) { - aDest = aMat; - } - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2], a03 = aMat[3]; - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6], a13 = aMat[7]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10], a23 = aMat[11]; - let a30 = aMat[12], a31 = aMat[13], a32 = aMat[14], a33 = aMat[15]; - - let b00 = a00 * a11 - a01 * a10; - let b01 = a00 * a12 - a02 * a10; - let b02 = a00 * a13 - a03 * a10; - let b03 = a01 * a12 - a02 * a11; - let b04 = a01 * a13 - a03 * a11; - let b05 = a02 * a13 - a03 * a12; - let b06 = a20 * a31 - a21 * a30; - let b07 = a20 * a32 - a22 * a30; - let b08 = a20 * a33 - a23 * a30; - let b09 = a21 * a32 - a22 * a31; - let b10 = a21 * a33 - a23 * a31; - let b11 = a22 * a33 - a23 * a32; - let id = 1 / ((b00 * b11 - b01 * b10 + b02 * b09 + - b03 * b08 - b04 * b07 + b05 * b06) || EPSILON); - - aDest[0] = ( a11 * b11 - a12 * b10 + a13 * b09) * id; - aDest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * id; - aDest[2] = ( a31 * b05 - a32 * b04 + a33 * b03) * id; - aDest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * id; - aDest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * id; - aDest[5] = ( a00 * b11 - a02 * b08 + a03 * b07) * id; - aDest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * id; - aDest[7] = ( a20 * b05 - a22 * b02 + a23 * b01) * id; - aDest[8] = ( a10 * b10 - a11 * b08 + a13 * b06) * id; - aDest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * id; - aDest[10] = ( a30 * b04 - a31 * b02 + a33 * b00) * id; - aDest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * id; - aDest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * id; - aDest[13] = ( a00 * b09 - a01 * b07 + a02 * b06) * id; - aDest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * id; - aDest[15] = ( a20 * b03 - a21 * b01 + a22 * b00) * id; - return aDest; - }, - - /** - * Copies the upper 3x3 elements of a mat4 into another mat4. - * - * @param {Array} aMat - * mat4 containing values to copy - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - toRotationMat: function M4_toRotationMat(aMat, aDest) - { - if (!aDest) { - aDest = new Float32Array(16); - } - - aDest[0] = aMat[0]; - aDest[1] = aMat[1]; - aDest[2] = aMat[2]; - aDest[3] = aMat[3]; - aDest[4] = aMat[4]; - aDest[5] = aMat[5]; - aDest[6] = aMat[6]; - aDest[7] = aMat[7]; - aDest[8] = aMat[8]; - aDest[9] = aMat[9]; - aDest[10] = aMat[10]; - aDest[11] = aMat[11]; - aDest[12] = 0; - aDest[13] = 0; - aDest[14] = 0; - aDest[15] = 1; - return aDest; - }, - - /** - * Copies the upper 3x3 elements of a mat4 into a mat3. - * - * @param {Array} aMat - * mat4 containing values to copy - * @param {Array} aDest - * optional, mat3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat3 if specified, first operand otherwise - */ - toMat3: function M4_toMat3(aMat, aDest) - { - if (!aDest) { - aDest = new Float32Array(9); - } - - aDest[0] = aMat[0]; - aDest[1] = aMat[1]; - aDest[2] = aMat[2]; - aDest[3] = aMat[4]; - aDest[4] = aMat[5]; - aDest[5] = aMat[6]; - aDest[6] = aMat[8]; - aDest[7] = aMat[9]; - aDest[8] = aMat[10]; - return aDest; - }, - - /** - * Calculate the inverse of the upper 3x3 elements of a mat4 and copies - * the result into a mat3. The resulting matrix is useful for calculating - * transformed normals. - * - * @param {Array} aMat - * mat4 containing values to invert and copy - * @param {Array} aDest - * optional, mat3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat3 if specified, first operand otherwise - */ - toInverseMat3: function M4_toInverseMat3(aMat, aDest) - { - if (!aDest) { - aDest = new Float32Array(9); - } - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2]; - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10]; - - let b01 = a22 * a11 - a12 * a21; - let b11 = -a22 * a10 + a12 * a20; - let b21 = a21 * a10 - a11 * a20; - let id = 1 / ((a00 * b01 + a01 * b11 + a02 * b21) || EPSILON); - - aDest[0] = b01 * id; - aDest[1] = (-a22 * a01 + a02 * a21) * id; - aDest[2] = ( a12 * a01 - a02 * a11) * id; - aDest[3] = b11 * id; - aDest[4] = ( a22 * a00 - a02 * a20) * id; - aDest[5] = (-a12 * a00 + a02 * a10) * id; - aDest[6] = b21 * id; - aDest[7] = (-a21 * a00 + a01 * a20) * id; - aDest[8] = ( a11 * a00 - a01 * a10) * id; - return aDest; - }, - - /** - * Performs a matrix multiplication. - * - * @param {Array} aMat - * first operand - * @param {Array} aMat2 - * second operand - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - multiply: function M4_multiply(aMat, aMat2, aDest) - { - if (!aDest) { - aDest = aMat; - } - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2], a03 = aMat[3]; - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6], a13 = aMat[7]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10], a23 = aMat[11]; - let a30 = aMat[12], a31 = aMat[13], a32 = aMat[14], a33 = aMat[15]; - - let b00 = aMat2[0], b01 = aMat2[1], b02 = aMat2[2], b03 = aMat2[3]; - let b10 = aMat2[4], b11 = aMat2[5], b12 = aMat2[6], b13 = aMat2[7]; - let b20 = aMat2[8], b21 = aMat2[9], b22 = aMat2[10], b23 = aMat2[11]; - let b30 = aMat2[12], b31 = aMat2[13], b32 = aMat2[14], b33 = aMat2[15]; - - aDest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30; - aDest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31; - aDest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32; - aDest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33; - aDest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30; - aDest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31; - aDest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32; - aDest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33; - aDest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30; - aDest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31; - aDest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32; - aDest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33; - aDest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30; - aDest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31; - aDest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32; - aDest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33; - return aDest; - }, - - /** - * Transforms a vec3 with the given matrix. - * 4th vector component is implicitly 1. - * - * @param {Array} aMat - * mat4 to transform the vector with - * @param {Array} aVec - * vec3 to transform - * @param {Array} aDest - * optional, vec3 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, aVec operand otherwise - */ - multiplyVec3: function M4_multiplyVec3(aMat, aVec, aDest) - { - if (!aDest) { - aDest = aVec; - } - - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - - aDest[0] = aMat[0] * x + aMat[4] * y + aMat[8] * z + aMat[12]; - aDest[1] = aMat[1] * x + aMat[5] * y + aMat[9] * z + aMat[13]; - aDest[2] = aMat[2] * x + aMat[6] * y + aMat[10] * z + aMat[14]; - return aDest; - }, - - /** - * Transforms a vec4 with the given matrix. - * - * @param {Array} aMat - * mat4 to transform the vector with - * @param {Array} aVec - * vec4 to transform - * @param {Array} aDest - * optional, vec4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec4 if specified, vec4 operand otherwise - */ - multiplyVec4: function M4_multiplyVec4(aMat, aVec, aDest) - { - if (!aDest) { - aDest = aVec; - } - - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - let w = aVec[3]; - - aDest[0] = aMat[0] * x + aMat[4] * y + aMat[8] * z + aMat[12] * w; - aDest[1] = aMat[1] * x + aMat[5] * y + aMat[9] * z + aMat[13] * w; - aDest[2] = aMat[2] * x + aMat[6] * y + aMat[10] * z + aMat[14] * w; - aDest[3] = aMat[3] * x + aMat[7] * y + aMat[11] * z + aMat[15] * w; - return aDest; - }, - - /** - * Translates a matrix by the given vector. - * - * @param {Array} aMat - * mat4 to translate - * @param {Array} aVec - * vec3 specifying the translation - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - translate: function M4_translate(aMat, aVec, aDest) - { - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - - if (!aDest || aMat === aDest) { - aMat[12] = aMat[0] * x + aMat[4] * y + aMat[8] * z + aMat[12]; - aMat[13] = aMat[1] * x + aMat[5] * y + aMat[9] * z + aMat[13]; - aMat[14] = aMat[2] * x + aMat[6] * y + aMat[10] * z + aMat[14]; - aMat[15] = aMat[3] * x + aMat[7] * y + aMat[11] * z + aMat[15]; - return aMat; - } - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2], a03 = aMat[3]; - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6], a13 = aMat[7]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10], a23 = aMat[11]; - - aDest[0] = a00; - aDest[1] = a01; - aDest[2] = a02; - aDest[3] = a03; - aDest[4] = a10; - aDest[5] = a11; - aDest[6] = a12; - aDest[7] = a13; - aDest[8] = a20; - aDest[9] = a21; - aDest[10] = a22; - aDest[11] = a23; - aDest[12] = a00 * x + a10 * y + a20 * z + aMat[12]; - aDest[13] = a01 * x + a11 * y + a21 * z + aMat[13]; - aDest[14] = a02 * x + a12 * y + a22 * z + aMat[14]; - aDest[15] = a03 * x + a13 * y + a23 * z + aMat[15]; - return aDest; - }, - - /** - * Scales a matrix by the given vector. - * - * @param {Array} aMat - * mat4 to translate - * @param {Array} aVec - * vec3 specifying the scale on each axis - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - scale: function M4_scale(aMat, aVec, aDest) - { - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - - if (!aDest || aMat === aDest) { - aMat[0] *= x; - aMat[1] *= x; - aMat[2] *= x; - aMat[3] *= x; - aMat[4] *= y; - aMat[5] *= y; - aMat[6] *= y; - aMat[7] *= y; - aMat[8] *= z; - aMat[9] *= z; - aMat[10] *= z; - aMat[11] *= z; - return aMat; - } - - aDest[0] = aMat[0] * x; - aDest[1] = aMat[1] * x; - aDest[2] = aMat[2] * x; - aDest[3] = aMat[3] * x; - aDest[4] = aMat[4] * y; - aDest[5] = aMat[5] * y; - aDest[6] = aMat[6] * y; - aDest[7] = aMat[7] * y; - aDest[8] = aMat[8] * z; - aDest[9] = aMat[9] * z; - aDest[10] = aMat[10] * z; - aDest[11] = aMat[11] * z; - aDest[12] = aMat[12]; - aDest[13] = aMat[13]; - aDest[14] = aMat[14]; - aDest[15] = aMat[15]; - return aDest; - }, - - /** - * Rotates a matrix by the given angle around the specified axis. - * If rotating around a primary axis (x, y, z) one of the specialized - * rotation functions should be used instead for performance, - * - * @param {Array} aMat - * mat4 to rotate - * @param {Number} aAngle - * the angle (in radians) to rotate - * @param {Array} aAxis - * vec3 representing the axis to rotate around - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - rotate: function M4_rotate(aMat, aAngle, aAxis, aDest) - { - let x = aAxis[0]; - let y = aAxis[1]; - let z = aAxis[2]; - let len = 1 / (Math.sqrt(x * x + y * y + z * z) || EPSILON); - - x *= len; - y *= len; - z *= len; - - let s = Math.sin(aAngle); - let c = Math.cos(aAngle); - let t = 1 - c; - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2], a03 = aMat[3]; - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6], a13 = aMat[7]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10], a23 = aMat[11]; - - let b00 = x * x * t + c, b01 = y * x * t + z * s, b02 = z * x * t - y * s; - let b10 = x * y * t - z * s, b11 = y * y * t + c, b12 = z * y * t + x * s; - let b20 = x * z * t + y * s, b21 = y * z * t - x * s, b22 = z * z * t + c; - - if (!aDest) { - aDest = aMat; - } else if (aMat !== aDest) { - aDest[12] = aMat[12]; - aDest[13] = aMat[13]; - aDest[14] = aMat[14]; - aDest[15] = aMat[15]; - } - - aDest[0] = a00 * b00 + a10 * b01 + a20 * b02; - aDest[1] = a01 * b00 + a11 * b01 + a21 * b02; - aDest[2] = a02 * b00 + a12 * b01 + a22 * b02; - aDest[3] = a03 * b00 + a13 * b01 + a23 * b02; - aDest[4] = a00 * b10 + a10 * b11 + a20 * b12; - aDest[5] = a01 * b10 + a11 * b11 + a21 * b12; - aDest[6] = a02 * b10 + a12 * b11 + a22 * b12; - aDest[7] = a03 * b10 + a13 * b11 + a23 * b12; - aDest[8] = a00 * b20 + a10 * b21 + a20 * b22; - aDest[9] = a01 * b20 + a11 * b21 + a21 * b22; - aDest[10] = a02 * b20 + a12 * b21 + a22 * b22; - aDest[11] = a03 * b20 + a13 * b21 + a23 * b22; - return aDest; - }, - - /** - * Rotates a matrix by the given angle around the X axis. - * - * @param {Array} aMat - * mat4 to rotate - * @param {Number} aAngle - * the angle (in radians) to rotate - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - rotateX: function M4_rotateX(aMat, aAngle, aDest) - { - let s = Math.sin(aAngle); - let c = Math.cos(aAngle); - - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6], a13 = aMat[7]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10], a23 = aMat[11]; - - if (!aDest) { - aDest = aMat; - } else if (aMat !== aDest) { - aDest[0] = aMat[0]; - aDest[1] = aMat[1]; - aDest[2] = aMat[2]; - aDest[3] = aMat[3]; - aDest[12] = aMat[12]; - aDest[13] = aMat[13]; - aDest[14] = aMat[14]; - aDest[15] = aMat[15]; - } - - aDest[4] = a10 * c + a20 * s; - aDest[5] = a11 * c + a21 * s; - aDest[6] = a12 * c + a22 * s; - aDest[7] = a13 * c + a23 * s; - aDest[8] = a10 * -s + a20 * c; - aDest[9] = a11 * -s + a21 * c; - aDest[10] = a12 * -s + a22 * c; - aDest[11] = a13 * -s + a23 * c; - return aDest; - }, - - /** - * Rotates a matrix by the given angle around the Y axix. - * - * @param {Array} aMat - * mat4 to rotate - * @param {Number} aAngle - * the angle (in radians) to rotate - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - rotateY: function M4_rotateY(aMat, aAngle, aDest) - { - let s = Math.sin(aAngle); - let c = Math.cos(aAngle); - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2], a03 = aMat[3]; - let a20 = aMat[8], a21 = aMat[9], a22 = aMat[10], a23 = aMat[11]; - - if (!aDest) { - aDest = aMat; - } else if (aMat !== aDest) { - aDest[4] = aMat[4]; - aDest[5] = aMat[5]; - aDest[6] = aMat[6]; - aDest[7] = aMat[7]; - aDest[12] = aMat[12]; - aDest[13] = aMat[13]; - aDest[14] = aMat[14]; - aDest[15] = aMat[15]; - } - - aDest[0] = a00 * c + a20 * -s; - aDest[1] = a01 * c + a21 * -s; - aDest[2] = a02 * c + a22 * -s; - aDest[3] = a03 * c + a23 * -s; - aDest[8] = a00 * s + a20 * c; - aDest[9] = a01 * s + a21 * c; - aDest[10] = a02 * s + a22 * c; - aDest[11] = a03 * s + a23 * c; - return aDest; - }, - - /** - * Rotates a matrix by the given angle around the Z axix. - * - * @param {Array} aMat - * mat4 to rotate - * @param {Number} aAngle - * the angle (in radians) to rotate - * @param {Array} aDest - * optional, mat4 receiving operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - rotateZ: function M4_rotateZ(aMat, aAngle, aDest) - { - let s = Math.sin(aAngle); - let c = Math.cos(aAngle); - - let a00 = aMat[0], a01 = aMat[1], a02 = aMat[2], a03 = aMat[3]; - let a10 = aMat[4], a11 = aMat[5], a12 = aMat[6], a13 = aMat[7]; - - if (!aDest) { - aDest = aMat; - } else if (aMat !== aDest) { - aDest[8] = aMat[8]; - aDest[9] = aMat[9]; - aDest[10] = aMat[10]; - aDest[11] = aMat[11]; - aDest[12] = aMat[12]; - aDest[13] = aMat[13]; - aDest[14] = aMat[14]; - aDest[15] = aMat[15]; - } - - aDest[0] = a00 * c + a10 * s; - aDest[1] = a01 * c + a11 * s; - aDest[2] = a02 * c + a12 * s; - aDest[3] = a03 * c + a13 * s; - aDest[4] = a00 * -s + a10 * c; - aDest[5] = a01 * -s + a11 * c; - aDest[6] = a02 * -s + a12 * c; - aDest[7] = a03 * -s + a13 * c; - return aDest; - }, - - /** - * Generates a frustum matrix with the given bounds. - * - * @param {Number} aLeft - * scalar, left bound of the frustum - * @param {Number} aRight - * scalar, right bound of the frustum - * @param {Number} aBottom - * scalar, bottom bound of the frustum - * @param {Number} aTop - * scalar, top bound of the frustum - * @param {Number} aNear - * scalar, near bound of the frustum - * @param {Number} aFar - * scalar, far bound of the frustum - * @param {Array} aDest - * optional, mat4 frustum matrix will be written into - * if not specified result is written to a new mat4 - * - * @return {Array} the destination mat4 if specified, a new mat4 otherwise - */ - frustum: function M4_frustum( - aLeft, aRight, aBottom, aTop, aNear, aFar, aDest) - { - if (!aDest) { - aDest = new Float32Array(16); - } - - let rl = (aRight - aLeft); - let tb = (aTop - aBottom); - let fn = (aFar - aNear); - - aDest[0] = (aNear * 2) / rl; - aDest[1] = 0; - aDest[2] = 0; - aDest[3] = 0; - aDest[4] = 0; - aDest[5] = (aNear * 2) / tb; - aDest[6] = 0; - aDest[7] = 0; - aDest[8] = (aRight + aLeft) / rl; - aDest[9] = (aTop + aBottom) / tb; - aDest[10] = -(aFar + aNear) / fn; - aDest[11] = -1; - aDest[12] = 0; - aDest[13] = 0; - aDest[14] = -(aFar * aNear * 2) / fn; - aDest[15] = 0; - return aDest; - }, - - /** - * Generates a perspective projection matrix with the given bounds. - * - * @param {Number} aFovy - * scalar, vertical field of view (degrees) - * @param {Number} aAspect - * scalar, aspect ratio (typically viewport width/height) - * @param {Number} aNear - * scalar, near bound of the frustum - * @param {Number} aFar - * scalar, far bound of the frustum - * @param {Array} aDest - * optional, mat4 frustum matrix will be written into - * if not specified result is written to a new mat4 - * - * @return {Array} the destination mat4 if specified, a new mat4 otherwise - */ - perspective: function M4_perspective( - aFovy, aAspect, aNear, aFar, aDest, aFlip) - { - let upper = aNear * Math.tan(aFovy * 0.00872664626); // PI * 180 / 2 - let right = upper * aAspect; - let top = upper * (aFlip || 1); - - return mat4.frustum(-right, right, -top, top, aNear, aFar, aDest); - }, - - /** - * Generates a orthogonal projection matrix with the given bounds. - * - * @param {Number} aLeft - * scalar, left bound of the frustum - * @param {Number} aRight - * scalar, right bound of the frustum - * @param {Number} aBottom - * scalar, bottom bound of the frustum - * @param {Number} aTop - * scalar, top bound of the frustum - * @param {Number} aNear - * scalar, near bound of the frustum - * @param {Number} aFar - * scalar, far bound of the frustum - * @param {Array} aDest - * optional, mat4 frustum matrix will be written into - * if not specified result is written to a new mat4 - * - * @return {Array} the destination mat4 if specified, a new mat4 otherwise - */ - ortho: function M4_ortho(aLeft, aRight, aBottom, aTop, aNear, aFar, aDest) - { - if (!aDest) { - aDest = new Float32Array(16); - } - - let rl = (aRight - aLeft); - let tb = (aTop - aBottom); - let fn = (aFar - aNear); - - aDest[0] = 2 / rl; - aDest[1] = 0; - aDest[2] = 0; - aDest[3] = 0; - aDest[4] = 0; - aDest[5] = 2 / tb; - aDest[6] = 0; - aDest[7] = 0; - aDest[8] = 0; - aDest[9] = 0; - aDest[10] = -2 / fn; - aDest[11] = 0; - aDest[12] = -(aLeft + aRight) / rl; - aDest[13] = -(aTop + aBottom) / tb; - aDest[14] = -(aFar + aNear) / fn; - aDest[15] = 1; - return aDest; - }, - - /** - * Generates a look-at matrix with the given eye position, focal point, and - * up axis. - * - * @param {Array} aEye - * vec3, position of the viewer - * @param {Array} aCenter - * vec3, point the viewer is looking at - * @param {Array} aUp - * vec3 pointing up - * @param {Array} aDest - * optional, mat4 frustum matrix will be written into - * if not specified result is written to a new mat4 - * - * @return {Array} the destination mat4 if specified, a new mat4 otherwise - */ - lookAt: function M4_lookAt(aEye, aCenter, aUp, aDest) - { - if (!aDest) { - aDest = new Float32Array(16); - } - - let eyex = aEye[0]; - let eyey = aEye[1]; - let eyez = aEye[2]; - let upx = aUp[0]; - let upy = aUp[1]; - let upz = aUp[2]; - let centerx = aCenter[0]; - let centery = aCenter[1]; - let centerz = aCenter[2]; - - let z0 = eyex - aCenter[0]; - let z1 = eyey - aCenter[1]; - let z2 = eyez - aCenter[2]; - let len = 1 / (Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2) || EPSILON); - - z0 *= len; - z1 *= len; - z2 *= len; - - let x0 = upy * z2 - upz * z1; - let x1 = upz * z0 - upx * z2; - let x2 = upx * z1 - upy * z0; - len = 1 / (Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2) || EPSILON); - - x0 *= len; - x1 *= len; - x2 *= len; - - let y0 = z1 * x2 - z2 * x1; - let y1 = z2 * x0 - z0 * x2; - let y2 = z0 * x1 - z1 * x0; - len = 1 / (Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2) || EPSILON); - - y0 *= len; - y1 *= len; - y2 *= len; - - aDest[0] = x0; - aDest[1] = y0; - aDest[2] = z0; - aDest[3] = 0; - aDest[4] = x1; - aDest[5] = y1; - aDest[6] = z1; - aDest[7] = 0; - aDest[8] = x2; - aDest[9] = y2; - aDest[10] = z2; - aDest[11] = 0; - aDest[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); - aDest[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); - aDest[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); - aDest[15] = 1; - - return aDest; - }, - - /** - * Returns a string representation of a 4x4 matrix. - * - * @param {Array} aMat - * mat4 to represent as a string - * - * @return {String} representation of the matrix - */ - str: function M4_str(mat) - { - return "[" + mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + - ", "+ mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + - ", "+ mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + - ", "+ mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15] + - "]"; - } -}; - -exports.mat4 = mat4; - -/** - * quat4 - Quaternion. - */ -var quat4 = { - - /** - * Creates a new instance of a quat4 using the default Float32Array type. - * Any array containing at least 4 numeric elements can serve as a quat4. - * - * @param {Array} aQuat - * optional, quat4 containing values to initialize with - * - * @return {Array} a new instance of a quat4 - */ - create: function Q4_create(aQuat) - { - let dest = new Float32Array(4); - - if (aQuat) { - quat4.set(aQuat, dest); - } else { - quat4.identity(dest); - } - return dest; - }, - - /** - * Copies the values of one quat4 to another. - * - * @param {Array} aQuat - * quat4 containing values to copy - * @param {Array} aDest - * quat4 receiving copied values - * - * @return {Array} the destination quat4 receiving copied values - */ - set: function Q4_set(aQuat, aDest) - { - aDest[0] = aQuat[0]; - aDest[1] = aQuat[1]; - aDest[2] = aQuat[2]; - aDest[3] = aQuat[3]; - return aDest; - }, - - /** - * Sets a quat4 to an identity quaternion. - * - * @param {Array} aDest - * quat4 to set - * - * @return {Array} the same quaternion - */ - identity: function Q4_identity(aDest) - { - aDest[0] = 0; - aDest[1] = 0; - aDest[2] = 0; - aDest[3] = 1; - return aDest; - }, - - /** - * Calculate the W component of a quat4 from the X, Y, and Z components. - * Assumes that quaternion is 1 unit in length. - * Any existing W component will be ignored. - * - * @param {Array} aQuat - * quat4 to calculate W component of - * @param {Array} aDest - * optional, quat4 receiving calculated values - * if not specified result is written to the first operand - * - * @return {Array} the destination quat if specified, first operand otherwise - */ - calculateW: function Q4_calculateW(aQuat, aDest) - { - if (!aDest) { - aDest = aQuat; - } - - let x = aQuat[0]; - let y = aQuat[1]; - let z = aQuat[2]; - - aDest[0] = x; - aDest[1] = y; - aDest[2] = z; - aDest[3] = -Math.sqrt(Math.abs(1 - x * x - y * y - z * z)); - return aDest; - }, - - /** - * Calculate the inverse of a quat4. - * - * @param {Array} aQuat - * quat4 to calculate the inverse of - * @param {Array} aDest - * optional, quat4 receiving the inverse values - * if not specified result is written to the first operand - * - * @return {Array} the destination quat if specified, first operand otherwise - */ - inverse: function Q4_inverse(aQuat, aDest) - { - if (!aDest) { - aDest = aQuat; - } - - aQuat[0] = -aQuat[0]; - aQuat[1] = -aQuat[1]; - aQuat[2] = -aQuat[2]; - return aQuat; - }, - - /** - * Generates a unit quaternion of the same direction as the provided quat4. - * If quaternion length is 0, returns [0, 0, 0, 0]. - * - * @param {Array} aQuat - * quat4 to normalize - * @param {Array} aDest - * optional, quat4 receiving the operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination quat if specified, first operand otherwise - */ - normalize: function Q4_normalize(aQuat, aDest) - { - if (!aDest) { - aDest = aQuat; - } - - let x = aQuat[0]; - let y = aQuat[1]; - let z = aQuat[2]; - let w = aQuat[3]; - let len = Math.sqrt(x * x + y * y + z * z + w * w); - - if (Math.abs(len) < EPSILON) { - aDest[0] = 0; - aDest[1] = 0; - aDest[2] = 0; - aDest[3] = 0; - return aDest; - } - - len = 1 / len; - aDest[0] = x * len; - aDest[1] = y * len; - aDest[2] = z * len; - aDest[3] = w * len; - return aDest; - }, - - /** - * Calculate the length of a quat4. - * - * @param {Array} aQuat - * quat4 to calculate the length of - * - * @return {Number} length of the quaternion - */ - length: function Q4_length(aQuat) - { - let x = aQuat[0]; - let y = aQuat[1]; - let z = aQuat[2]; - let w = aQuat[3]; - - return Math.sqrt(x * x + y * y + z * z + w * w); - }, - - /** - * Performs a quaternion multiplication. - * - * @param {Array} aQuat - * first operand - * @param {Array} aQuat2 - * second operand - * @param {Array} aDest - * optional, quat4 receiving the operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination quat if specified, first operand otherwise - */ - multiply: function Q4_multiply(aQuat, aQuat2, aDest) - { - if (!aDest) { - aDest = aQuat; - } - - let qax = aQuat[0]; - let qay = aQuat[1]; - let qaz = aQuat[2]; - let qaw = aQuat[3]; - let qbx = aQuat2[0]; - let qby = aQuat2[1]; - let qbz = aQuat2[2]; - let qbw = aQuat2[3]; - - aDest[0] = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; - aDest[1] = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; - aDest[2] = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; - aDest[3] = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - return aDest; - }, - - /** - * Transforms a vec3 with the given quaternion. - * - * @param {Array} aQuat - * quat4 to transform the vector with - * @param {Array} aVec - * vec3 to transform - * @param {Array} aDest - * optional, vec3 receiving the operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination vec3 if specified, aVec operand otherwise - */ - multiplyVec3: function Q4_multiplyVec3(aQuat, aVec, aDest) - { - if (!aDest) { - aDest = aVec; - } - - let x = aVec[0]; - let y = aVec[1]; - let z = aVec[2]; - - let qx = aQuat[0]; - let qy = aQuat[1]; - let qz = aQuat[2]; - let qw = aQuat[3]; - - let ix = qw * x + qy * z - qz * y; - let iy = qw * y + qz * x - qx * z; - let iz = qw * z + qx * y - qy * x; - let iw = -qx * x - qy * y - qz * z; - - aDest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; - aDest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; - aDest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; - return aDest; - }, - - /** - * Performs a spherical linear interpolation between two quat4. - * - * @param {Array} aQuat - * first quaternion - * @param {Array} aQuat2 - * second quaternion - * @param {Number} aSlerp - * interpolation amount between the two inputs - * @param {Array} aDest - * optional, quat4 receiving the operation result - * if not specified result is written to the first operand - * - * @return {Array} the destination quat if specified, first operand otherwise - */ - slerp: function Q4_slerp(aQuat, aQuat2, aSlerp, aDest) - { - if (!aDest) { - aDest = aQuat; - } - - let cosHalfTheta = aQuat[0] * aQuat2[0] + - aQuat[1] * aQuat2[1] + - aQuat[2] * aQuat2[2] + - aQuat[3] * aQuat2[3]; - - if (Math.abs(cosHalfTheta) >= 1) { - aDest[0] = aQuat[0]; - aDest[1] = aQuat[1]; - aDest[2] = aQuat[2]; - aDest[3] = aQuat[3]; - return aDest; - } - - let halfTheta = Math.acos(cosHalfTheta); - let sinHalfTheta = Math.sqrt(1 - cosHalfTheta * cosHalfTheta); - - if (Math.abs(sinHalfTheta) < EPSILON) { - aDest[0] = (aQuat[0] * 0.5 + aQuat2[0] * 0.5); - aDest[1] = (aQuat[1] * 0.5 + aQuat2[1] * 0.5); - aDest[2] = (aQuat[2] * 0.5 + aQuat2[2] * 0.5); - aDest[3] = (aQuat[3] * 0.5 + aQuat2[3] * 0.5); - return aDest; - } - - let ratioA = Math.sin((1 - aSlerp) * halfTheta) / sinHalfTheta; - let ratioB = Math.sin(aSlerp * halfTheta) / sinHalfTheta; - - aDest[0] = (aQuat[0] * ratioA + aQuat2[0] * ratioB); - aDest[1] = (aQuat[1] * ratioA + aQuat2[1] * ratioB); - aDest[2] = (aQuat[2] * ratioA + aQuat2[2] * ratioB); - aDest[3] = (aQuat[3] * ratioA + aQuat2[3] * ratioB); - return aDest; - }, - - /** - * Calculates a 3x3 matrix from the given quat4. - * - * @param {Array} aQuat - * quat4 to create matrix from - * @param {Array} aDest - * optional, mat3 receiving the initialization result - * if not specified, a new matrix is created - * - * @return {Array} the destination mat3 if specified, first operand otherwise - */ - toMat3: function Q4_toMat3(aQuat, aDest) - { - if (!aDest) { - aDest = new Float32Array(9); - } - - let x = aQuat[0]; - let y = aQuat[1]; - let z = aQuat[2]; - let w = aQuat[3]; - - let x2 = x + x; - let y2 = y + y; - let z2 = z + z; - let xx = x * x2; - let xy = x * y2; - let xz = x * z2; - let yy = y * y2; - let yz = y * z2; - let zz = z * z2; - let wx = w * x2; - let wy = w * y2; - let wz = w * z2; - - aDest[0] = 1 - (yy + zz); - aDest[1] = xy - wz; - aDest[2] = xz + wy; - aDest[3] = xy + wz; - aDest[4] = 1 - (xx + zz); - aDest[5] = yz - wx; - aDest[6] = xz - wy; - aDest[7] = yz + wx; - aDest[8] = 1 - (xx + yy); - return aDest; - }, - - /** - * Calculates a 4x4 matrix from the given quat4. - * - * @param {Array} aQuat - * quat4 to create matrix from - * @param {Array} aDest - * optional, mat4 receiving the initialization result - * if not specified, a new matrix is created - * - * @return {Array} the destination mat4 if specified, first operand otherwise - */ - toMat4: function Q4_toMat4(aQuat, aDest) - { - if (!aDest) { - aDest = new Float32Array(16); - } - - let x = aQuat[0]; - let y = aQuat[1]; - let z = aQuat[2]; - let w = aQuat[3]; - - let x2 = x + x; - let y2 = y + y; - let z2 = z + z; - let xx = x * x2; - let xy = x * y2; - let xz = x * z2; - let yy = y * y2; - let yz = y * z2; - let zz = z * z2; - let wx = w * x2; - let wy = w * y2; - let wz = w * z2; - - aDest[0] = 1 - (yy + zz); - aDest[1] = xy - wz; - aDest[2] = xz + wy; - aDest[3] = 0; - aDest[4] = xy + wz; - aDest[5] = 1 - (xx + zz); - aDest[6] = yz - wx; - aDest[7] = 0; - aDest[8] = xz - wy; - aDest[9] = yz + wx; - aDest[10] = 1 - (xx + yy); - aDest[11] = 0; - aDest[12] = 0; - aDest[13] = 0; - aDest[14] = 0; - aDest[15] = 1; - return aDest; - }, - - /** - * Creates a rotation quaternion from axis-angle. - * This function expects that the axis is a normalized vector. - * - * @param {Array} aAxis - * an array of elements representing the [x, y, z] axis - * @param {Number} aAngle - * the angle of rotation - * @param {Array} aDest - * optional, quat4 receiving the initialization result - * if not specified, a new quaternion is created - * - * @return {Array} the quaternion as [x, y, z, w] - */ - fromAxis: function Q4_fromAxis(aAxis, aAngle, aDest) - { - if (!aDest) { - aDest = new Float32Array(4); - } - - let ang = aAngle * 0.5; - let sin = Math.sin(ang); - let cos = Math.cos(ang); - - aDest[0] = aAxis[0] * sin; - aDest[1] = aAxis[1] * sin; - aDest[2] = aAxis[2] * sin; - aDest[3] = cos; - return aDest; - }, - - /** - * Creates a rotation quaternion from Euler angles. - * - * @param {Number} aYaw - * the yaw angle of rotation - * @param {Number} aPitch - * the pitch angle of rotation - * @param {Number} aRoll - * the roll angle of rotation - * @param {Array} aDest - * optional, quat4 receiving the initialization result - * if not specified, a new quaternion is created - * - * @return {Array} the quaternion as [x, y, z, w] - */ - fromEuler: function Q4_fromEuler(aYaw, aPitch, aRoll, aDest) - { - if (!aDest) { - aDest = new Float32Array(4); - } - - let x = aPitch * 0.5; - let y = aYaw * 0.5; - let z = aRoll * 0.5; - - let sinr = Math.sin(x); - let sinp = Math.sin(y); - let siny = Math.sin(z); - let cosr = Math.cos(x); - let cosp = Math.cos(y); - let cosy = Math.cos(z); - - aDest[0] = sinr * cosp * cosy - cosr * sinp * siny; - aDest[1] = cosr * sinp * cosy + sinr * cosp * siny; - aDest[2] = cosr * cosp * siny - sinr * sinp * cosy; - aDest[3] = cosr * cosp * cosy + sinr * sinp * siny; - return aDest; - }, - - /** - * Returns a string representation of a quaternion. - * - * @param {Array} aQuat - * quat4 to represent as a string - * - * @return {String} representation of the quaternion - */ - str: function Q4_str(aQuat) { - return "[" + aQuat[0] + ", " + - aQuat[1] + ", " + - aQuat[2] + ", " + - aQuat[3] + "]"; - } -}; - -exports.quat4 = quat4; - -/** - * Various algebraic math functions required by the engine. - */ -var TiltMath = { - - /** - * Helper function, converts degrees to radians. - * - * @param {Number} aDegrees - * the degrees to be converted to radians - * - * @return {Number} the degrees converted to radians - */ - radians: function TM_radians(aDegrees) - { - return aDegrees * PI_OVER_180; - }, - - /** - * Helper function, converts radians to degrees. - * - * @param {Number} aRadians - * the radians to be converted to degrees - * - * @return {Number} the radians converted to degrees - */ - degrees: function TM_degrees(aRadians) - { - return aRadians * INV_PI_OVER_180; - }, - - /** - * Re-maps a number from one range to another. - * - * @param {Number} aValue - * the number to map - * @param {Number} aLow1 - * the normal lower bound of the number - * @param {Number} aHigh1 - * the normal upper bound of the number - * @param {Number} aLow2 - * the new lower bound of the number - * @param {Number} aHigh2 - * the new upper bound of the number - * - * @return {Number} the remapped number - */ - map: function TM_map(aValue, aLow1, aHigh1, aLow2, aHigh2) - { - return aLow2 + (aHigh2 - aLow2) * ((aValue - aLow1) / (aHigh1 - aLow1)); - }, - - /** - * Returns if number is power of two. - * - * @param {Number} aNumber - * the number to be verified - * - * @return {Boolean} true if x is power of two - */ - isPowerOfTwo: function TM_isPowerOfTwo(aNumber) - { - return !(aNumber & (aNumber - 1)); - }, - - /** - * Returns the next closest power of two greater than a number. - * - * @param {Number} aNumber - * the number to be converted - * - * @return {Number} the next closest power of two for x - */ - nextPowerOfTwo: function TM_nextPowerOfTwo(aNumber) - { - --aNumber; - - for (let i = 1; i < 32; i <<= 1) { - aNumber = aNumber | aNumber >> i; - } - return aNumber + 1; - }, - - /** - * A convenient way of limiting values to a set boundary. - * - * @param {Number} aValue - * the number to be limited - * @param {Number} aMin - * the minimum allowed value for the number - * @param {Number} aMax - * the maximum allowed value for the number - */ - clamp: function TM_clamp(aValue, aMin, aMax) - { - return Math.max(aMin, Math.min(aMax, aValue)); - }, - - /** - * Convenient way to clamp a value to 0..1 - * - * @param {Number} aValue - * the number to be limited - */ - saturate: function TM_saturate(aValue) - { - return Math.max(0, Math.min(1, aValue)); - }, - - /** - * Converts a hex color to rgba. - * If the passed param is invalid, it will be converted to [0, 0, 0, 1]; - * - * @param {String} aColor - * color expressed in hex, or using rgb() or rgba() - * - * @return {Array} with 4 color 0..1 components: [red, green, blue, alpha] - */ - hex2rgba: (function() - { - let cache = {}; - - return function TM_hex2rgba(aColor) { - let hex = aColor.charAt(0) === "#" ? aColor.substring(1) : aColor; - - // check the cache to see if this color wasn't converted already - if (cache[hex] !== undefined) { - return cache[hex]; - } - - // e.g. "f00" - if (hex.length === 3) { - let r = parseInt(hex.substring(0, 1), 16) * FIFTEEN_OVER_225; - let g = parseInt(hex.substring(1, 2), 16) * FIFTEEN_OVER_225; - let b = parseInt(hex.substring(2, 3), 16) * FIFTEEN_OVER_225; - - return (cache[hex] = [r, g, b, 1]); - } - // e.g. "f008" - if (hex.length === 4) { - let r = parseInt(hex.substring(0, 1), 16) * FIFTEEN_OVER_225; - let g = parseInt(hex.substring(1, 2), 16) * FIFTEEN_OVER_225; - let b = parseInt(hex.substring(2, 3), 16) * FIFTEEN_OVER_225; - let a = parseInt(hex.substring(3, 4), 16) * FIFTEEN_OVER_225; - - return (cache[hex] = [r, g, b, a]); - } - // e.g. "ff0000" - if (hex.length === 6) { - let r = parseInt(hex.substring(0, 2), 16) * ONE_OVER_255; - let g = parseInt(hex.substring(2, 4), 16) * ONE_OVER_255; - let b = parseInt(hex.substring(4, 6), 16) * ONE_OVER_255; - let a = 1; - - return (cache[hex] = [r, g, b, a]); - } - // e.g "ff0000aa" - if (hex.length === 8) { - let r = parseInt(hex.substring(0, 2), 16) * ONE_OVER_255; - let g = parseInt(hex.substring(2, 4), 16) * ONE_OVER_255; - let b = parseInt(hex.substring(4, 6), 16) * ONE_OVER_255; - let a = parseInt(hex.substring(6, 8), 16) * ONE_OVER_255; - - return (cache[hex] = [r, g, b, a]); - } - // e.g. "rgba(255, 0, 0, 0.5)" - if (hex.match("^rgba")) { - let rgba = hex.substring(5, hex.length - 1).split(","); - rgba[0] *= ONE_OVER_255; - rgba[1] *= ONE_OVER_255; - rgba[2] *= ONE_OVER_255; - // in CSS, the alpha component of rgba() is already in the range 0..1 - - return (cache[hex] = rgba); - } - // e.g. "rgb(255, 0, 0)" - if (hex.match("^rgb")) { - let rgba = hex.substring(4, hex.length - 1).split(","); - rgba[0] *= ONE_OVER_255; - rgba[1] *= ONE_OVER_255; - rgba[2] *= ONE_OVER_255; - rgba[3] = 1; - - return (cache[hex] = rgba); - } - - // your argument is invalid - return (cache[hex] = [0, 0, 0, 1]); - }; - }()) -}; - -exports.TiltMath = TiltMath; - -// bind the owner object to the necessary functions -TiltUtils.bindObjectFunc(vec3); -TiltUtils.bindObjectFunc(mat3); -TiltUtils.bindObjectFunc(mat4); -TiltUtils.bindObjectFunc(quat4); -TiltUtils.bindObjectFunc(TiltMath); diff --git a/devtools/client/tilt/tilt-utils.js b/devtools/client/tilt/tilt-utils.js deleted file mode 100644 index 8e593e67798d..000000000000 --- a/devtools/client/tilt/tilt-utils.js +++ /dev/null @@ -1,614 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {Cc, Ci, Cu} = require("chrome"); -const {getRect} = require("devtools/shared/layout/utils"); -const Services = require("Services"); - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const STACK_THICKNESS = 15; - -/** - * Module containing various helper functions used throughout Tilt. - */ -this.TiltUtils = {}; -module.exports = this.TiltUtils; - -/** - * Various console/prompt output functions required by the engine. - */ -TiltUtils.Output = { - - /** - * Logs a message to the console. - * - * @param {String} aMessage - * the message to be logged - */ - log: function TUO_log(aMessage) - { - if (this.suppressLogs) { - return; - } - // get the console service - let consoleService = Cc["@mozilla.org/consoleservice;1"] - .getService(Ci.nsIConsoleService); - - // log the message - consoleService.logStringMessage(aMessage); - }, - - /** - * Logs an error to the console. - * - * @param {String} aMessage - * the message to be logged - * @param {Object} aProperties - * and object containing script error initialization details - */ - error: function TUO_error(aMessage, aProperties) - { - if (this.suppressErrors) { - return; - } - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - // get the console service - let consoleService = Cc["@mozilla.org/consoleservice;1"] - .getService(Ci.nsIConsoleService); - - // get the script error service - let scriptError = Cc["@mozilla.org/scripterror;1"] - .createInstance(Ci.nsIScriptError); - - // initialize a script error - scriptError.init(aMessage, - aProperties.sourceName || "", - aProperties.sourceLine || "", - aProperties.lineNumber || 0, - aProperties.columnNumber || 0, - aProperties.flags || 0, - aProperties.category || ""); - - // log the error - consoleService.logMessage(scriptError); - }, - - /** - * Shows a modal alert message popup. - * - * @param {String} aTitle - * the title of the popup - * @param {String} aMessage - * the message to be logged - */ - alert: function TUO_alert(aTitle, aMessage) - { - if (this.suppressAlerts) { - return; - } - if (!aMessage) { - aMessage = aTitle; - aTitle = ""; - } - - // get the prompt service - let prompt = Cc["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Ci.nsIPromptService); - - // show the alert message - prompt.alert(null, aTitle, aMessage); - } -}; - -/** - * Helper functions for managing preferences. - */ -TiltUtils.Preferences = { - - /** - * Gets a custom Tilt preference. - * If the preference does not exist, undefined is returned. If it does exist, - * but the type is not correctly specified, null is returned. - * - * @param {String} aPref - * the preference name - * @param {String} aType - * either "boolean", "string" or "integer" - * - * @return {Boolean | String | Number} the requested preference - */ - get: function TUP_get(aPref, aType) - { - if (!aPref || !aType) { - return; - } - - try { - let prefs = this._branch; - - switch(aType) { - case "boolean": - return prefs.getBoolPref(aPref); - case "string": - return prefs.getCharPref(aPref); - case "integer": - return prefs.getIntPref(aPref); - } - return null; - - } catch(e) { - // handle any unexpected exceptions - TiltUtils.Output.error(e.message); - return undefined; - } - }, - - /** - * Sets a custom Tilt preference. - * If the preference already exists, it is overwritten. - * - * @param {String} aPref - * the preference name - * @param {String} aType - * either "boolean", "string" or "integer" - * @param {String} aValue - * a new preference value - * - * @return {Boolean} true if the preference was set successfully - */ - set: function TUP_set(aPref, aType, aValue) - { - if (!aPref || !aType || aValue === undefined || aValue === null) { - return; - } - - try { - let prefs = this._branch; - - switch(aType) { - case "boolean": - return prefs.setBoolPref(aPref, aValue); - case "string": - return prefs.setCharPref(aPref, aValue); - case "integer": - return prefs.setIntPref(aPref, aValue); - } - } catch(e) { - // handle any unexpected exceptions - TiltUtils.Output.error(e.message); - } - return false; - }, - - /** - * Creates a custom Tilt preference. - * If the preference already exists, it is left unchanged. - * - * @param {String} aPref - * the preference name - * @param {String} aType - * either "boolean", "string" or "integer" - * @param {String} aValue - * the initial preference value - * - * @return {Boolean} true if the preference was initialized successfully - */ - create: function TUP_create(aPref, aType, aValue) - { - if (!aPref || !aType || aValue === undefined || aValue === null) { - return; - } - - try { - let prefs = this._branch; - - if (!prefs.prefHasUserValue(aPref)) { - switch(aType) { - case "boolean": - return prefs.setBoolPref(aPref, aValue); - case "string": - return prefs.setCharPref(aPref, aValue); - case "integer": - return prefs.setIntPref(aPref, aValue); - } - } - } catch(e) { - // handle any unexpected exceptions - TiltUtils.Output.error(e.message); - } - return false; - }, - - /** - * The preferences branch for this extension. - */ - _branch: (function(aBranch) { - return Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService) - .getBranch(aBranch); - - }("devtools.tilt.")) -}; - -/** - * Easy way to access the string bundle. - */ -TiltUtils.L10n = { - - /** - * The string bundle element. - */ - stringBundle: null, - - /** - * Returns a string in the string bundle. - * If the string bundle is not found, null is returned. - * - * @param {String} aName - * the string name in the bundle - * - * @return {String} the equivalent string from the bundle - */ - get: function TUL_get(aName) - { - // check to see if the parent string bundle document element is valid - if (!this.stringBundle || !aName) { - return null; - } - return this.stringBundle.GetStringFromName(aName); - }, - - /** - * Returns a formatted string using the string bundle. - * If the string bundle is not found, null is returned. - * - * @param {String} aName - * the string name in the bundle - * @param {Array} aArgs - * an array of arguments for the formatted string - * - * @return {String} the equivalent formatted string from the bundle - */ - format: function TUL_format(aName, aArgs) - { - // check to see if the parent string bundle document element is valid - if (!this.stringBundle || !aName || !aArgs) { - return null; - } - return this.stringBundle.formatStringFromName(aName, aArgs, aArgs.length); - } -}; - -/** - * Utilities for accessing and manipulating a document. - */ -TiltUtils.DOM = { - - /** - * Current parent node object used when creating canvas elements. - */ - parentNode: null, - - /** - * Helper method, allowing to easily create and manage a canvas element. - * If the width and height params are falsy, they default to the parent node - * client width and height. - * - * @param {Document} aParentNode - * the parent node used to create the canvas - * if not specified, it will be reused from the cache - * @param {Object} aProperties - * optional, object containing some of the following props: - * {Boolean} focusable - * optional, true to make the canvas focusable - * {Boolean} append - * optional, true to append the canvas to the parent node - * {Number} width - * optional, specifies the width of the canvas - * {Number} height - * optional, specifies the height of the canvas - * {String} id - * optional, id for the created canvas element - * - * @return {HTMLCanvasElement} the newly created canvas element - */ - initCanvas: function TUD_initCanvas(aParentNode, aProperties) - { - // check to see if the parent node element is valid - if (!(aParentNode = aParentNode || this.parentNode)) { - return null; - } - - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - // cache this parent node so that it can be reused - this.parentNode = aParentNode; - - // create the canvas element - let canvas = aParentNode.ownerDocument. - createElementNS("http://www.w3.org/1999/xhtml", "canvas"); - - let width = aProperties.width || aParentNode.clientWidth; - let height = aProperties.height || aParentNode.clientHeight; - let id = aProperties.id || null; - - canvas.setAttribute("style", "min-width: 1px; min-height: 1px;"); - canvas.setAttribute("width", width); - canvas.setAttribute("height", height); - canvas.setAttribute("id", id); - - // the canvas is unfocusable by default, we may require otherwise - if (aProperties.focusable) { - canvas.setAttribute("tabindex", "1"); - canvas.style.outline = "none"; - } - - // append the canvas element to the current parent node, if specified - if (aProperties.append) { - aParentNode.appendChild(canvas); - } - - return canvas; - }, - - /** - * Gets the full webpage dimensions (width and height). - * - * @param {Window} aContentWindow - * the content window holding the document - * - * @return {Object} an object containing the width and height coords - */ - getContentWindowDimensions: function TUD_getContentWindowDimensions( - aContentWindow) - { - return { - width: aContentWindow.innerWidth + - aContentWindow.scrollMaxX - aContentWindow.scrollMinX, - height: aContentWindow.innerHeight + - aContentWindow.scrollMaxY - aContentWindow.scrollMinY - }; - }, - - /** - * Calculates the position and depth to display a node, this can be overriden - * to change the visualization. - * - * @param {Window} aContentWindow - * the window content holding the document - * @param {Node} aNode - * the node to get the position for - * @param {Object} aParentPosition - * the position of the parent node, as returned by this - * function - * - * @return {Object} an object describing the node's position in 3D space - * containing the following properties: - * {Number} top - * distance along the x axis - * {Number} left - * distance along the y axis - * {Number} depth - * distance along the z axis - * {Number} width - * width of the node - * {Number} height - * height of the node - * {Number} thickness - * thickness of the node - */ - getNodePosition: function TUD_getNodePosition(aContentWindow, aNode, - aParentPosition) { - // get the x, y, width and height coordinates of the node - let coord = getRect(aContentWindow, aNode, aContentWindow); - if (!coord) { - return null; - } - - coord.depth = aParentPosition ? (aParentPosition.depth + aParentPosition.thickness) : 0; - coord.thickness = STACK_THICKNESS; - - return coord; - }, - - /** - * Traverses a document object model & calculates useful info for each node. - * - * @param {Window} aContentWindow - * the window content holding the document - * @param {Object} aProperties - * optional, an object containing the following properties: - * {Function} nodeCallback - * a function to call instead of TiltUtils.DOM.getNodePosition - * to get the position and depth to display nodes - * {Object} invisibleElements - * elements which should be ignored - * {Number} minSize - * the minimum dimensions needed for a node to be traversed - * {Number} maxX - * the maximum left position of an element - * {Number} maxY - * the maximum top position of an element - * - * @return {Array} list containing nodes positions and local names - */ - traverse: function TUD_traverse(aContentWindow, aProperties) - { - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - let aInvisibleElements = aProperties.invisibleElements || {}; - let aMinSize = aProperties.minSize || -1; - let aMaxX = aProperties.maxX || Number.MAX_VALUE; - let aMaxY = aProperties.maxY || Number.MAX_VALUE; - - let nodeCallback = aProperties.nodeCallback || this.getNodePosition.bind(this); - - let nodes = aContentWindow.document.childNodes; - let store = { info: [], nodes: [] }; - let depth = 0; - - let queue = [ - { parentPosition: null, nodes: aContentWindow.document.childNodes } - ] - - while (queue.length) { - let { nodes, parentPosition } = queue.shift(); - - for (let node of nodes) { - // skip some nodes to avoid visualization meshes that are too bloated - let name = node.localName; - if (!name || aInvisibleElements[name]) { - continue; - } - - let coord = nodeCallback(aContentWindow, node, parentPosition); - if (!coord) { - continue; - } - - // the maximum size slices the traversal where needed - if (coord.left > aMaxX || coord.top > aMaxY) { - continue; - } - - // use this node only if it actually has visible dimensions - if (coord.width > aMinSize && coord.height > aMinSize) { - - // save the necessary details into a list to be returned later - store.info.push({ coord: coord, name: name }); - store.nodes.push(node); - } - - let childNodes = (name === "iframe" || name === "frame") ? node.contentDocument.childNodes : node.childNodes; - if (childNodes.length > 0) - queue.push({ parentPosition: coord, nodes: childNodes }); - } - } - - return store; - } -}; - -/** - * Binds a new owner object to the child functions. - * If the new parent is not specified, it will default to the passed scope. - * - * @param {Object} aScope - * the object from which all functions will be rebound - * @param {String} aRegex - * a regular expression to identify certain functions - * @param {Object} aParent - * the new parent for the object's functions - */ -TiltUtils.bindObjectFunc = function TU_bindObjectFunc(aScope, aRegex, aParent) -{ - if (!aScope) { - return; - } - - for (let i in aScope) { - try { - if ("function" === typeof aScope[i] && (aRegex ? i.match(aRegex) : 1)) { - aScope[i] = aScope[i].bind(aParent || aScope); - } - } catch(e) { - TiltUtils.Output.error(e); - } - } -}; - -/** - * Destroys an object and deletes all members. - * - * @param {Object} aScope - * the object from which all children will be destroyed - */ -TiltUtils.destroyObject = function TU_destroyObject(aScope) -{ - if (!aScope) { - return; - } - - // objects in Tilt usually use a function to handle internal destruction - if ("function" === typeof aScope._finalize) { - aScope._finalize(); - } - for (let i in aScope) { - if (aScope.hasOwnProperty(i)) { - delete aScope[i]; - } - } -}; - -/** - * Retrieve the unique ID of a window object. - * - * @param {Window} aWindow - * the window to get the ID from - * - * @return {Number} the window ID - */ -TiltUtils.getWindowId = function TU_getWindowId(aWindow) -{ - if (!aWindow) { - return; - } - - return aWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .currentInnerWindowID; -}; - -/** - * Sets the markup document viewer zoom for the currently selected browser. - * - * @param {Window} aChromeWindow - * the top-level browser window - * - * @param {Number} the zoom ammount - */ -TiltUtils.setDocumentZoom = function TU_setDocumentZoom(aChromeWindow, aZoom) { - aChromeWindow.gBrowser.selectedBrowser.markupDocumentViewer.fullZoom = aZoom; -}; - -/** - * Performs a garbage collection. - * - * @param {Window} aChromeWindow - * the top-level browser window - */ -TiltUtils.gc = function TU_gc(aChromeWindow) -{ - aChromeWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .garbageCollect(); -}; - -/** - * Clears the cache and sets all the variables to null. - */ -TiltUtils.clearCache = function TU_clearCache() -{ - TiltUtils.DOM.parentNode = null; -}; - -// bind the owner object to the necessary functions -TiltUtils.bindObjectFunc(TiltUtils.Output); -TiltUtils.bindObjectFunc(TiltUtils.Preferences); -TiltUtils.bindObjectFunc(TiltUtils.L10n); -TiltUtils.bindObjectFunc(TiltUtils.DOM); - -// set the necessary string bundle -XPCOMUtils.defineLazyGetter(TiltUtils.L10n, "stringBundle", function() { - return Services.strings.createBundle( - "chrome://devtools/locale/tilt.properties"); -}); diff --git a/devtools/client/tilt/tilt-visualizer-style.js b/devtools/client/tilt/tilt-visualizer-style.js deleted file mode 100644 index 4891ba7f4f73..000000000000 --- a/devtools/client/tilt/tilt-visualizer-style.js +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -var {TiltMath} = require("devtools/client/tilt/tilt-math"); -var rgba = TiltMath.hex2rgba; - -/** - * Various colors and style settings used throughout Tilt. - */ -module.exports = { - canvas: { - background: "linear-gradient(#454545 0%, #000 100%)", - }, - - nodes: { - highlight: { - defaultFill: rgba("#555"), - defaultStroke: rgba("#000"), - defaultStrokeWeight: 1 - }, - - html: rgba("#8880"), - body: rgba("#fff0"), - h1: rgba("#e667af"), - h2: rgba("#c667af"), - h3: rgba("#a667af"), - h4: rgba("#8667af"), - h5: rgba("#8647af"), - h6: rgba("#8627af"), - div: rgba("#5dc8cd"), - span: rgba("#67e46f"), - table: rgba("#ff0700"), - tr: rgba("#ff4540"), - td: rgba("#ff7673"), - ul: rgba("#4671d5"), - li: rgba("#6c8cd5"), - p: rgba("#aaa"), - a: rgba("#123eab"), - img: rgba("#ffb473"), - iframe: rgba("#85004b") - } -}; diff --git a/devtools/client/tilt/tilt-visualizer.js b/devtools/client/tilt/tilt-visualizer.js deleted file mode 100644 index eae44566e97a..000000000000 --- a/devtools/client/tilt/tilt-visualizer.js +++ /dev/null @@ -1,2255 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {Cu, Ci, ChromeWorker} = require("chrome"); - -var Services = require("Services"); -var TiltGL = require("devtools/client/tilt/tilt-gl"); -var TiltUtils = require("devtools/client/tilt/tilt-utils"); -var TiltVisualizerStyle = require("devtools/client/tilt/tilt-visualizer-style"); -var {EPSILON, TiltMath, vec3, mat4, quat4} = require("devtools/client/tilt/tilt-math"); -var {TargetFactory} = require("devtools/client/framework/target"); -var {gDevTools} = require("devtools/client/framework/devtools"); - -const ELEMENT_MIN_SIZE = 4; -const INVISIBLE_ELEMENTS = { - "head": true, - "base": true, - "basefont": true, - "isindex": true, - "link": true, - "meta": true, - "option": true, - "script": true, - "style": true, - "title": true -}; - -// a node is represented in the visualization mesh as a rectangular stack -// of 5 quads composed of 12 vertices; we draw these as triangles using an -// index buffer of 12 unsigned int elements, obviously one for each vertex; -// if a webpage has enough nodes to overflow the index buffer elements size, -// weird things may happen; thus, when necessary, we'll split into groups -const MAX_GROUP_NODES = Math.pow(2, Uint16Array.BYTES_PER_ELEMENT * 8) / 12 - 1; - -const WIREFRAME_COLOR = [0, 0, 0, 0.25]; -const INTRO_TRANSITION_DURATION = 1000; -const OUTRO_TRANSITION_DURATION = 800; -const INITIAL_Z_TRANSLATION = 400; -const MOVE_INTO_VIEW_ACCURACY = 50; - -const MOUSE_CLICK_THRESHOLD = 10; -const MOUSE_INTRO_DELAY = 200; -const ARCBALL_SENSITIVITY = 0.5; -const ARCBALL_ROTATION_STEP = 0.15; -const ARCBALL_TRANSLATION_STEP = 35; -const ARCBALL_ZOOM_STEP = 0.1; -const ARCBALL_ZOOM_MIN = -3000; -const ARCBALL_ZOOM_MAX = 500; -const ARCBALL_RESET_SPHERICAL_FACTOR = 0.1; -const ARCBALL_RESET_LINEAR_FACTOR = 0.01; - -const TILT_CRAFTER = - "resource://devtools/client/tilt/TiltWorkerCrafter.js"; -const TILT_PICKER = - "resource://devtools/client/tilt/TiltWorkerPicker.js"; - - -/** - * Initializes the visualization presenter and controller. - * - * @param {Object} aProperties - * an object containing the following properties: - * {Window} chromeWindow: a reference to the top level window - * {Window} contentWindow: the content window holding the visualized doc - * {Element} parentNode: the parent node to hold the visualization - * {Object} notifications: necessary notifications for Tilt - * {Function} onError: optional, function called if initialization failed - * {Function} onLoad: optional, function called if initialization worked - */ -function TiltVisualizer(aProperties) -{ - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - /** - * Save a reference to the top-level window. - */ - this.chromeWindow = aProperties.chromeWindow; - this.tab = aProperties.tab; - - /** - * The canvas element used for rendering the visualization. - */ - this.canvas = TiltUtils.DOM.initCanvas(aProperties.parentNode, { - focusable: true, - append: true - }); - - /** - * Visualization logic and drawing loop. - */ - this.presenter = new TiltVisualizer.Presenter(this.canvas, - aProperties.chromeWindow, - aProperties.contentWindow, - aProperties.notifications, - aProperties.onError || null, - aProperties.onLoad || null); - - /** - * Visualization mouse and keyboard controller. - */ - this.controller = new TiltVisualizer.Controller(this.canvas, this.presenter); -} - -exports.TiltVisualizer = TiltVisualizer; - -TiltVisualizer.prototype = { - - /** - * Initializes the visualizer. - */ - init: function TV_init() - { - this.presenter.init(); - this.bindToInspector(this.tab); - }, - - /** - * Checks if this object was initialized properly. - * - * @return {Boolean} true if the object was initialized properly - */ - isInitialized: function TV_isInitialized() - { - return this.presenter && this.presenter.isInitialized() && - this.controller && this.controller.isInitialized(); - }, - - /** - * Removes the overlay canvas used for rendering the visualization. - */ - removeOverlay: function TV_removeOverlay() - { - if (this.canvas && this.canvas.parentNode) { - this.canvas.parentNode.removeChild(this.canvas); - } - }, - - /** - * Explicitly cleans up this visualizer and sets everything to null. - */ - cleanup: function TV_cleanup() - { - this.unbindInspector(); - - if (this.controller) { - TiltUtils.destroyObject(this.controller); - } - if (this.presenter) { - TiltUtils.destroyObject(this.presenter); - } - - let chromeWindow = this.chromeWindow; - - TiltUtils.destroyObject(this); - TiltUtils.clearCache(); - TiltUtils.gc(chromeWindow); - }, - - /** - * Listen to the inspector activity. - */ - bindToInspector: function TV_bindToInspector(aTab) - { - this._browserTab = aTab; - - this.onNewNodeFromInspector = this.onNewNodeFromInspector.bind(this); - this.onNewNodeFromTilt = this.onNewNodeFromTilt.bind(this); - this.onInspectorReady = this.onInspectorReady.bind(this); - this.onToolboxDestroyed = this.onToolboxDestroyed.bind(this); - - gDevTools.on("inspector-ready", this.onInspectorReady); - gDevTools.on("toolbox-destroyed", this.onToolboxDestroyed); - - Services.obs.addObserver(this.onNewNodeFromTilt, - this.presenter.NOTIFICATIONS.HIGHLIGHTING, - false); - Services.obs.addObserver(this.onNewNodeFromTilt, - this.presenter.NOTIFICATIONS.UNHIGHLIGHTING, - false); - - let target = TargetFactory.forTab(aTab); - let toolbox = gDevTools.getToolbox(target); - if (toolbox) { - let panel = toolbox.getPanel("inspector"); - if (panel) { - this.inspector = panel; - this.inspector.selection.on("new-node", this.onNewNodeFromInspector); - this.onNewNodeFromInspector(); - } - } - }, - - /** - * Unregister inspector event listeners. - */ - unbindInspector: function TV_unbindInspector() - { - this._browserTab = null; - - if (this.inspector) { - if (this.inspector.selection) { - this.inspector.selection.off("new-node", this.onNewNodeFromInspector); - } - this.inspector = null; - } - - gDevTools.off("inspector-ready", this.onInspectorReady); - gDevTools.off("toolbox-destroyed", this.onToolboxDestroyed); - - Services.obs.removeObserver(this.onNewNodeFromTilt, - this.presenter.NOTIFICATIONS.HIGHLIGHTING); - Services.obs.removeObserver(this.onNewNodeFromTilt, - this.presenter.NOTIFICATIONS.UNHIGHLIGHTING); - }, - - /** - * When a new inspector is started. - */ - onInspectorReady: function TV_onInspectorReady(event, toolbox, panel) - { - if (toolbox.target.tab === this._browserTab) { - this.inspector = panel; - this.inspector.selection.on("new-node", this.onNewNodeFromInspector); - this.onNewNodeFromTilt(); - } - }, - - /** - * When the toolbox, therefor the inspector, is closed. - */ - onToolboxDestroyed: function TV_onToolboxDestroyed(event, tab) - { - if (tab === this._browserTab && - this.inspector) { - if (this.inspector.selection) { - this.inspector.selection.off("new-node", this.onNewNodeFromInspector); - } - this.inspector = null; - } - }, - - /** - * When a new node is selected in the inspector. - */ - onNewNodeFromInspector: function TV_onNewNodeFromInspector() - { - if (this.inspector && - this.inspector.selection.reason != "tilt") { - let selection = this.inspector.selection; - let canHighlightNode = selection.isNode() && - selection.isConnected() && - selection.isElementNode(); - if (canHighlightNode) { - this.presenter.highlightNode(selection.node); - } else { - this.presenter.highlightNodeFor(-1); - } - } - }, - - /** - * When a new node is selected in Tilt. - */ - onNewNodeFromTilt: function TV_onNewNodeFromTilt() - { - if (!this.inspector) { - return; - } - let nodeIndex = this.presenter._currentSelection; - if (nodeIndex < 0) { - this.inspector.selection.setNodeFront(null, "tilt"); - } - let node = this.presenter._traverseData.nodes[nodeIndex]; - node = this.inspector.walker.frontForRawNode(node); - this.inspector.selection.setNodeFront(node, "tilt"); - }, -}; - -/** - * This object manages the visualization logic and drawing loop. - * - * @param {HTMLCanvasElement} aCanvas - * the canvas element used for rendering - * @param {Window} aChromeWindow - * a reference to the top-level window - * @param {Window} aContentWindow - * the content window holding the document to be visualized - * @param {Object} aNotifications - * necessary notifications for Tilt - * @param {Function} onError - * function called if initialization failed - * @param {Function} onLoad - * function called if initialization worked - */ -TiltVisualizer.Presenter = function TV_Presenter( - aCanvas, aChromeWindow, aContentWindow, aNotifications, onError, onLoad) -{ - /** - * A canvas overlay used for drawing the visualization. - */ - this.canvas = aCanvas; - - /** - * Save a reference to the top-level window, to access Tilt. - */ - this.chromeWindow = aChromeWindow; - - /** - * The content window generating the visualization - */ - this.contentWindow = aContentWindow; - - /** - * Shortcut for accessing notifications strings. - */ - this.NOTIFICATIONS = aNotifications; - - /** - * Use the default node callback function - */ - this.nodeCallback = null; - - /** - * Create the renderer, containing useful functions for easy drawing. - */ - this._renderer = new TiltGL.Renderer(aCanvas, onError, onLoad); - - /** - * A custom shader used for drawing the visualization mesh. - */ - this._visualizationProgram = null; - - /** - * The combined mesh representing the document visualization. - */ - this._texture = null; - this._meshData = null; - this._meshStacks = null; - this._meshWireframe = null; - this._traverseData = null; - - /** - * A highlight quad drawn over a stacked dom node. - */ - this._highlight = { - disabled: true, - v0: vec3.create(), - v1: vec3.create(), - v2: vec3.create(), - v3: vec3.create() - }; - - /** - * Scene transformations, exposing offset, translation and rotation. - * Modified by events in the controller through delegate functions. - */ - this.transforms = { - zoom: 1, - offset: vec3.create(), // mesh offset, aligned to the viewport center - translation: vec3.create(), // scene translation, on the [x, y, z] axis - rotation: quat4.create() // scene rotation, expressed as a quaternion - }; - - /** - * Variables holding information about the initial and current node selected. - */ - this._currentSelection = -1; // the selected node index - this._initialMeshConfiguration = false; // true if the 3D mesh was configured - - /** - * Variable specifying if the scene should be redrawn. - * This should happen usually when the visualization is translated/rotated. - */ - this._redraw = true; - - /** - * Total time passed since the rendering started. - * If the rendering is paused, this property won't get updated. - */ - this._time = 0; - - /** - * Frame delta time (the ammount of time passed for each frame). - * This is used to smoothly interpolate animation transfroms. - */ - this._delta = 0; - this._prevFrameTime = 0; - this._currFrameTime = 0; -}; - -TiltVisualizer.Presenter.prototype = { - - /** - * Initializes the presenter and starts the animation loop - */ - init: function TVP_init() - { - this._setup(); - this._loop(); - }, - - /** - * The initialization logic. - */ - _setup: function TVP__setup() - { - let renderer = this._renderer; - - // if the renderer was destroyed, don't continue setup - if (!renderer || !renderer.context) { - return; - } - - // create the visualization shaders and program to draw the stacks mesh - this._visualizationProgram = new renderer.Program({ - vs: TiltVisualizer.MeshShader.vs, - fs: TiltVisualizer.MeshShader.fs, - attributes: ["vertexPosition", "vertexTexCoord", "vertexColor"], - uniforms: ["mvMatrix", "projMatrix", "sampler"] - }); - - // get the document zoom to properly scale the visualization - this.transforms.zoom = this._getPageZoom(); - - // bind the owner object to the necessary functions - TiltUtils.bindObjectFunc(this, "^_on"); - TiltUtils.bindObjectFunc(this, "_loop"); - - this._setupTexture(); - this._setupMeshData(); - this._setupEventListeners(); - this.canvas.focus(); - }, - - /** - * Get page zoom factor. - * @return {Number} - */ - _getPageZoom: function TVP__getPageZoom() { - return this.contentWindow - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .fullZoom; - }, - - /** - * The animation logic. - */ - _loop: function TVP__loop() - { - let renderer = this._renderer; - let frameStartTime = this.chromeWindow.performance.now(); - - // if the renderer was destroyed, don't continue rendering - if (!renderer || !renderer.context) { - return; - } - - // prepare for the next frame of the animation loop - this.chromeWindow.requestAnimationFrame(this._loop); - - // only redraw if we really have to - if (this._redraw) { - this._redraw = false; - this._drawVisualization(); - } - - // update the current presenter transfroms from the controller - if ("function" === typeof this._controllerUpdate) { - this._controllerUpdate(this._time, this._delta); - } - - this._handleFrameDelta(frameStartTime); - this._handleKeyframeNotifications(); - }, - - /** - * Calculates the current frame delta time. - */ - _handleFrameDelta: function TVP__handleFrameDelta(frameStartTime) - { - this._prevFrameTime = this._currFrameTime; - this._currFrameTime = frameStartTime; - this._delta = this._currFrameTime - this._prevFrameTime; - }, - - /** - * Draws the visualization mesh and highlight quad. - */ - _drawVisualization: function TVP__drawVisualization() - { - let renderer = this._renderer; - let transforms = this.transforms; - let w = renderer.width; - let h = renderer.height; - let ih = renderer.initialHeight; - - // if the mesh wasn't created yet, don't continue rendering - if (!this._meshStacks || !this._meshWireframe) { - return; - } - - // clear the context to an opaque black background - renderer.clear(); - renderer.perspective(); - - // apply a transition transformation using an ortho and perspective matrix - let ortho = mat4.ortho(0, w, h, 0, -1000, 1000); - - if (!this._isExecutingDestruction) { - let f = this._time / INTRO_TRANSITION_DURATION; - renderer.lerp(renderer.projMatrix, ortho, f, 8); - } else { - let f = this._time / OUTRO_TRANSITION_DURATION; - renderer.lerp(renderer.projMatrix, ortho, 1 - f, 8); - } - - // apply the preliminary transformations to the model view - renderer.translate(w * 0.5, ih * 0.5, -INITIAL_Z_TRANSLATION); - - // calculate the camera matrix using the rotation and translation - renderer.translate(transforms.translation[0], 0, - transforms.translation[2]); - - renderer.transform(quat4.toMat4(transforms.rotation)); - - // offset the visualization mesh to center - renderer.translate(transforms.offset[0], - transforms.offset[1] + transforms.translation[1], 0); - - renderer.scale(transforms.zoom, transforms.zoom); - - // draw the visualization mesh - renderer.strokeWeight(2); - renderer.depthTest(true); - this._drawMeshStacks(); - this._drawMeshWireframe(); - this._drawHighlight(); - - // make sure the initial transition is drawn until finished - if (this._time < INTRO_TRANSITION_DURATION || - this._time < OUTRO_TRANSITION_DURATION) { - this._redraw = true; - } - this._time += this._delta; - }, - - /** - * Draws the meshStacks object. - */ - _drawMeshStacks: function TVP__drawMeshStacks() - { - let renderer = this._renderer; - let mesh = this._meshStacks; - - let visualizationProgram = this._visualizationProgram; - let texture = this._texture; - let mvMatrix = renderer.mvMatrix; - let projMatrix = renderer.projMatrix; - - // use the necessary shader - visualizationProgram.use(); - - for (let i = 0, len = mesh.length; i < len; i++) { - let group = mesh[i]; - - // bind the attributes and uniforms as necessary - visualizationProgram.bindVertexBuffer("vertexPosition", group.vertices); - visualizationProgram.bindVertexBuffer("vertexTexCoord", group.texCoord); - visualizationProgram.bindVertexBuffer("vertexColor", group.color); - - visualizationProgram.bindUniformMatrix("mvMatrix", mvMatrix); - visualizationProgram.bindUniformMatrix("projMatrix", projMatrix); - visualizationProgram.bindTexture("sampler", texture); - - // draw the vertices as TRIANGLES indexed elements - renderer.drawIndexedVertices(renderer.context.TRIANGLES, group.indices); - } - - // save the current model view and projection matrices - mesh.mvMatrix = mat4.create(mvMatrix); - mesh.projMatrix = mat4.create(projMatrix); - }, - - /** - * Draws the meshWireframe object. - */ - _drawMeshWireframe: function TVP__drawMeshWireframe() - { - let renderer = this._renderer; - let mesh = this._meshWireframe; - - for (let i = 0, len = mesh.length; i < len; i++) { - let group = mesh[i]; - - // use the necessary shader - renderer.useColorShader(group.vertices, WIREFRAME_COLOR); - - // draw the vertices as LINES indexed elements - renderer.drawIndexedVertices(renderer.context.LINES, group.indices); - } - }, - - /** - * Draws a highlighted quad around a currently selected node. - */ - _drawHighlight: function TVP__drawHighlight() - { - // check if there's anything to highlight (i.e any node is selected) - if (!this._highlight.disabled) { - - // set the corresponding state to draw the highlight quad - let renderer = this._renderer; - let highlight = this._highlight; - - renderer.depthTest(false); - renderer.fill(highlight.fill, 0.5); - renderer.stroke(highlight.stroke); - renderer.strokeWeight(highlight.strokeWeight); - renderer.quad(highlight.v0, highlight.v1, highlight.v2, highlight.v3); - } - }, - - /** - * Creates or refreshes the texture applied to the visualization mesh. - */ - _setupTexture: function TVP__setupTexture() - { - let renderer = this._renderer; - - // destroy any previously created texture - TiltUtils.destroyObject(this._texture); this._texture = null; - - // if the renderer was destroyed, don't continue setup - if (!renderer || !renderer.context) { - return; - } - - // get the maximum texture size - this._maxTextureSize = - renderer.context.getParameter(renderer.context.MAX_TEXTURE_SIZE); - - // use a simple shim to get the image representation of the document - // this will be removed once the MOZ_window_region_texture bug #653656 - // is finished; currently just converting the document image to a texture - // applied to the mesh - this._texture = new renderer.Texture({ - source: TiltGL.TextureUtils.createContentImage(this.contentWindow, - this._maxTextureSize), - format: "RGB" - }); - - if ("function" === typeof this._onSetupTexture) { - this._onSetupTexture(); - this._onSetupTexture = null; - } - }, - - /** - * Create the combined mesh representing the document visualization by - * traversing the document & adding a stack for each node that is drawable. - * - * @param {Object} aMeshData - * object containing the necessary mesh verts, texcoord etc. - */ - _setupMesh: function TVP__setupMesh(aMeshData) - { - let renderer = this._renderer; - - // destroy any previously created mesh - TiltUtils.destroyObject(this._meshStacks); this._meshStacks = []; - TiltUtils.destroyObject(this._meshWireframe); this._meshWireframe = []; - - // if the renderer was destroyed, don't continue setup - if (!renderer || !renderer.context) { - return; - } - - // save the mesh data for future use - this._meshData = aMeshData; - - // create a sub-mesh for each group in the mesh data - for (let i = 0, len = aMeshData.groups.length; i < len; i++) { - let group = aMeshData.groups[i]; - - // create the visualization mesh using the vertices, texture coordinates - // and indices computed when traversing the document object model - this._meshStacks.push({ - vertices: new renderer.VertexBuffer(group.vertices, 3), - texCoord: new renderer.VertexBuffer(group.texCoord, 2), - color: new renderer.VertexBuffer(group.color, 3), - indices: new renderer.IndexBuffer(group.stacksIndices) - }); - - // additionally, create a wireframe representation to make the - // visualization a bit more pretty - this._meshWireframe.push({ - vertices: this._meshStacks[i].vertices, - indices: new renderer.IndexBuffer(group.wireframeIndices) - }); - } - - // configure the required mesh transformations and background only once - if (!this._initialMeshConfiguration) { - this._initialMeshConfiguration = true; - - // set the necessary mesh offsets - this.transforms.offset[0] = -renderer.width * 0.5; - this.transforms.offset[1] = -renderer.height * 0.5; - - // make sure the canvas is opaque now that the initialization is finished - this.canvas.style.background = TiltVisualizerStyle.canvas.background; - - this._drawVisualization(); - this._redraw = true; - } - - if ("function" === typeof this._onSetupMesh) { - this._onSetupMesh(); - this._onSetupMesh = null; - } - }, - - /** - * Computes the mesh vertices, texture coordinates etc. by groups of nodes. - */ - _setupMeshData: function TVP__setupMeshData() - { - let renderer = this._renderer; - - // if the renderer was destroyed, don't continue setup - if (!renderer || !renderer.context) { - return; - } - - // traverse the document and get the depths, coordinates and local names - this._traverseData = TiltUtils.DOM.traverse(this.contentWindow, { - nodeCallback: this.nodeCallback, - invisibleElements: INVISIBLE_ELEMENTS, - minSize: ELEMENT_MIN_SIZE, - maxX: this._texture.width, - maxY: this._texture.height - }); - - let worker = new ChromeWorker(TILT_CRAFTER); - - worker.addEventListener("message", function TVP_onMessage(event) { - this._setupMesh(event.data); - }.bind(this), false); - - // calculate necessary information regarding vertices, texture coordinates - // etc. in a separate thread, as this process may take a while - worker.postMessage({ - maxGroupNodes: MAX_GROUP_NODES, - style: TiltVisualizerStyle.nodes, - texWidth: this._texture.width, - texHeight: this._texture.height, - nodesInfo: this._traverseData.info - }); - }, - - /** - * Sets up event listeners necessary for the presenter. - */ - _setupEventListeners: function TVP__setupEventListeners() - { - this.contentWindow.addEventListener("resize", this._onResize, false); - }, - - /** - * Called when the content window of the current browser is resized. - */ - _onResize: function TVP_onResize(e) - { - let zoom = this._getPageZoom(); - let width = e.target.innerWidth * zoom; - let height = e.target.innerHeight * zoom; - - // handle aspect ratio changes to update the projection matrix - this._renderer.width = width; - this._renderer.height = height; - - this._redraw = true; - }, - - /** - * Highlights a specific node. - * - * @param {Element} aNode - * the html node to be highlighted - * @param {String} aFlags - * flags specifying highlighting options - */ - highlightNode: function TVP_highlightNode(aNode, aFlags) - { - this.highlightNodeFor(this._traverseData.nodes.indexOf(aNode), aFlags); - }, - - /** - * Picks a stacked dom node at the x and y screen coordinates and highlights - * the selected node in the mesh. - * - * @param {Number} x - * the current horizontal coordinate of the mouse - * @param {Number} y - * the current vertical coordinate of the mouse - * @param {Object} aProperties - * an object containing the following properties: - * {Function} onpick: function to be called after picking succeeded - * {Function} onfail: function to be called after picking failed - */ - highlightNodeAt: function TVP_highlightNodeAt(x, y, aProperties) - { - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - // try to pick a mesh node using the current x, y coordinates - this.pickNode(x, y, { - - /** - * Mesh picking failed (nothing was found for the picked point). - */ - onfail: function TVP_onHighlightFail() - { - this.highlightNodeFor(-1); - - if ("function" === typeof aProperties.onfail) { - aProperties.onfail(); - } - }.bind(this), - - /** - * Mesh picking succeeded. - * - * @param {Object} aIntersection - * object containing the intersection details - */ - onpick: function TVP_onHighlightPick(aIntersection) - { - this.highlightNodeFor(aIntersection.index); - - if ("function" === typeof aProperties.onpick) { - aProperties.onpick(); - } - }.bind(this) - }); - }, - - /** - * Sets the corresponding highlight coordinates and color based on the - * information supplied. - * - * @param {Number} aNodeIndex - * the index of the node in the this._traverseData array - * @param {String} aFlags - * flags specifying highlighting options - */ - highlightNodeFor: function TVP_highlightNodeFor(aNodeIndex, aFlags) - { - this._redraw = true; - - // if the node was already selected, don't do anything - if (this._currentSelection === aNodeIndex) { - return; - } - - // if an invalid or nonexisted node is specified, disable the highlight - if (aNodeIndex < 0) { - this._currentSelection = -1; - this._highlight.disabled = true; - - Services.obs.notifyObservers(this.contentWindow, this.NOTIFICATIONS.UNHIGHLIGHTING, null); - return; - } - - let highlight = this._highlight; - let info = this._traverseData.info[aNodeIndex]; - let style = TiltVisualizerStyle.nodes; - - highlight.disabled = false; - highlight.fill = style[info.name] || style.highlight.defaultFill; - highlight.stroke = style.highlight.defaultStroke; - highlight.strokeWeight = style.highlight.defaultStrokeWeight; - - let x = info.coord.left; - let y = info.coord.top; - let w = info.coord.width; - let h = info.coord.height; - let z = info.coord.depth + info.coord.thickness; - - vec3.set([x, y, z], highlight.v0); - vec3.set([x + w, y, z], highlight.v1); - vec3.set([x + w, y + h, z], highlight.v2); - vec3.set([x, y + h, z], highlight.v3); - - this._currentSelection = aNodeIndex; - - // if something is highlighted, make sure it's inside the current viewport; - // the point which should be moved into view is considered the center [x, y] - // position along the top edge of the currently selected node - - if (aFlags && aFlags.indexOf("moveIntoView") !== -1) - { - this.controller.arcball.moveIntoView(vec3.lerp( - vec3.scale(this._highlight.v0, this.transforms.zoom, []), - vec3.scale(this._highlight.v1, this.transforms.zoom, []), 0.5)); - } - - Services.obs.notifyObservers(this.contentWindow, this.NOTIFICATIONS.HIGHLIGHTING, null); - }, - - /** - * Deletes a node from the visualization mesh. - * - * @param {Number} aNodeIndex - * the index of the node in the this._traverseData array; - * if not specified, it will default to the current selection - */ - deleteNode: function TVP_deleteNode(aNodeIndex) - { - // we probably don't want to delete the html or body node.. just sayin' - if ((aNodeIndex = aNodeIndex || this._currentSelection) < 1) { - return; - } - - let renderer = this._renderer; - - let groupIndex = parseInt(aNodeIndex / MAX_GROUP_NODES); - let nodeIndex = parseInt((aNodeIndex + (groupIndex ? 1 : 0)) % MAX_GROUP_NODES); - let group = this._meshStacks[groupIndex]; - let vertices = group.vertices.components; - - for (let i = 0, k = 36 * nodeIndex; i < 36; i++) { - vertices[i + k] = 0; - } - - group.vertices = new renderer.VertexBuffer(vertices, 3); - this._highlight.disabled = true; - this._redraw = true; - - Services.obs.notifyObservers(this.contentWindow, this.NOTIFICATIONS.NODE_REMOVED, null); - }, - - /** - * Picks a stacked dom node at the x and y screen coordinates and issues - * a callback function with the found intersection. - * - * @param {Number} x - * the current horizontal coordinate of the mouse - * @param {Number} y - * the current vertical coordinate of the mouse - * @param {Object} aProperties - * an object containing the following properties: - * {Function} onpick: function to be called at intersection - * {Function} onfail: function to be called if no intersections - */ - pickNode: function TVP_pickNode(x, y, aProperties) - { - // make sure the properties parameter is a valid object - aProperties = aProperties || {}; - - // if the mesh wasn't created yet, don't continue picking - if (!this._meshStacks || !this._meshWireframe) { - return; - } - - let worker = new ChromeWorker(TILT_PICKER); - - worker.addEventListener("message", function TVP_onMessage(event) { - if (event.data) { - if ("function" === typeof aProperties.onpick) { - aProperties.onpick(event.data); - } - } else { - if ("function" === typeof aProperties.onfail) { - aProperties.onfail(); - } - } - }, false); - - let zoom = this._getPageZoom(); - let width = this._renderer.width * zoom; - let height = this._renderer.height * zoom; - x *= zoom; - y *= zoom; - - // create a ray following the mouse direction from the near clipping plane - // to the far clipping plane, to check for intersections with the mesh, - // and do all the heavy lifting in a separate thread - worker.postMessage({ - vertices: this._meshData.allVertices, - - // create the ray destined for 3D picking - ray: vec3.createRay([x, y, 0], [x, y, 1], [0, 0, width, height], - this._meshStacks.mvMatrix, - this._meshStacks.projMatrix) - }); - }, - - /** - * Delegate translation method, used by the controller. - * - * @param {Array} aTranslation - * the new translation on the [x, y, z] axis - */ - setTranslation: function TVP_setTranslation(aTranslation) - { - let x = aTranslation[0]; - let y = aTranslation[1]; - let z = aTranslation[2]; - let transforms = this.transforms; - - // only update the translation if it's not already set - if (transforms.translation[0] !== x || - transforms.translation[1] !== y || - transforms.translation[2] !== z) { - - vec3.set(aTranslation, transforms.translation); - this._redraw = true; - } - }, - - /** - * Delegate rotation method, used by the controller. - * - * @param {Array} aQuaternion - * the rotation quaternion, as [x, y, z, w] - */ - setRotation: function TVP_setRotation(aQuaternion) - { - let x = aQuaternion[0]; - let y = aQuaternion[1]; - let z = aQuaternion[2]; - let w = aQuaternion[3]; - let transforms = this.transforms; - - // only update the rotation if it's not already set - if (transforms.rotation[0] !== x || - transforms.rotation[1] !== y || - transforms.rotation[2] !== z || - transforms.rotation[3] !== w) { - - quat4.set(aQuaternion, transforms.rotation); - this._redraw = true; - } - }, - - /** - * Handles notifications at specific frame counts. - */ - _handleKeyframeNotifications: function TV__handleKeyframeNotifications() - { - if (!TiltVisualizer.Prefs.introTransition && !this._isExecutingDestruction) { - this._time = INTRO_TRANSITION_DURATION; - } - if (!TiltVisualizer.Prefs.outroTransition && this._isExecutingDestruction) { - this._time = OUTRO_TRANSITION_DURATION; - } - - if (this._time >= INTRO_TRANSITION_DURATION && - !this._isInitializationFinished && - !this._isExecutingDestruction) { - - this._isInitializationFinished = true; - Services.obs.notifyObservers(this.contentWindow, this.NOTIFICATIONS.INITIALIZED, null); - - if ("function" === typeof this._onInitializationFinished) { - this._onInitializationFinished(); - } - } - - if (this._time >= OUTRO_TRANSITION_DURATION && - !this._isDestructionFinished && - this._isExecutingDestruction) { - - this._isDestructionFinished = true; - Services.obs.notifyObservers(this.contentWindow, this.NOTIFICATIONS.BEFORE_DESTROYED, null); - - if ("function" === typeof this._onDestructionFinished) { - this._onDestructionFinished(); - } - } - }, - - /** - * Starts executing the destruction sequence and issues a callback function - * when finished. - * - * @param {Function} aCallback - * the destruction finished callback - */ - executeDestruction: function TV_executeDestruction(aCallback) - { - if (!this._isExecutingDestruction) { - this._isExecutingDestruction = true; - this._onDestructionFinished = aCallback; - - // if we execute the destruction after the initialization finishes, - // proceed normally; otherwise, skip everything and immediately issue - // the callback - - if (this._time > OUTRO_TRANSITION_DURATION) { - this._time = 0; - this._redraw = true; - } else { - aCallback(); - } - } - }, - - /** - * Checks if this object was initialized properly. - * - * @return {Boolean} true if the object was initialized properly - */ - isInitialized: function TVP_isInitialized() - { - return this._renderer && this._renderer.context; - }, - - /** - * Function called when this object is destroyed. - */ - _finalize: function TVP__finalize() - { - TiltUtils.destroyObject(this._visualizationProgram); - TiltUtils.destroyObject(this._texture); - - if (this._meshStacks) { - this._meshStacks.forEach(function(group) { - TiltUtils.destroyObject(group.vertices); - TiltUtils.destroyObject(group.texCoord); - TiltUtils.destroyObject(group.color); - TiltUtils.destroyObject(group.indices); - }); - } - if (this._meshWireframe) { - this._meshWireframe.forEach(function(group) { - TiltUtils.destroyObject(group.indices); - }); - } - - TiltUtils.destroyObject(this._renderer); - - // Closing the tab would result in contentWindow being a dead object, - // so operations like removing event listeners won't work anymore. - if (this.contentWindow == this.chromeWindow.content) { - this.contentWindow.removeEventListener("resize", this._onResize, false); - } - } -}; - -/** - * A mouse and keyboard controller implementation. - * - * @param {HTMLCanvasElement} aCanvas - * the visualization canvas element - * @param {TiltVisualizer.Presenter} aPresenter - * the presenter instance to control - */ -TiltVisualizer.Controller = function TV_Controller(aCanvas, aPresenter) -{ - /** - * A canvas overlay on which mouse and keyboard event listeners are attached. - */ - this.canvas = aCanvas; - - /** - * Save a reference to the presenter to modify its model-view transforms. - */ - this.presenter = aPresenter; - this.presenter.controller = this; - - /** - * The initial controller dimensions and offset, in pixels. - */ - this._zoom = aPresenter.transforms.zoom; - this._left = (aPresenter.contentWindow.pageXOffset || 0) * this._zoom; - this._top = (aPresenter.contentWindow.pageYOffset || 0) * this._zoom; - this._width = aCanvas.width; - this._height = aCanvas.height; - - /** - * Arcball used to control the visualization using the mouse. - */ - this.arcball = new TiltVisualizer.Arcball( - this.presenter.chromeWindow, this._width, this._height, 0, - [ - this._width + this._left < aPresenter._maxTextureSize ? -this._left : 0, - this._height + this._top < aPresenter._maxTextureSize ? -this._top : 0 - ]); - - /** - * Object containing the rotation quaternion and the translation amount. - */ - this._coordinates = null; - - // bind the owner object to the necessary functions - TiltUtils.bindObjectFunc(this, "_update"); - TiltUtils.bindObjectFunc(this, "^_on"); - - // add the necessary event listeners - this.addEventListeners(); - - // attach this controller's update function to the presenter ondraw event - this.presenter._controllerUpdate = this._update; -}; - -TiltVisualizer.Controller.prototype = { - - /** - * Adds events listeners required by this controller. - */ - addEventListeners: function TVC_addEventListeners() - { - let canvas = this.canvas; - let presenter = this.presenter; - - // bind commonly used mouse and keyboard events with the controller - canvas.addEventListener("mousedown", this._onMouseDown, false); - canvas.addEventListener("mouseup", this._onMouseUp, false); - canvas.addEventListener("mousemove", this._onMouseMove, false); - canvas.addEventListener("mouseover", this._onMouseOver, false); - canvas.addEventListener("mouseout", this._onMouseOut, false); - canvas.addEventListener("MozMousePixelScroll", this._onMozScroll, false); - canvas.addEventListener("keydown", this._onKeyDown, false); - canvas.addEventListener("keyup", this._onKeyUp, false); - canvas.addEventListener("blur", this._onBlur, false); - - // handle resize events to change the arcball dimensions - presenter.contentWindow.addEventListener("resize", this._onResize, false); - }, - - /** - * Removes all added events listeners required by this controller. - */ - removeEventListeners: function TVC_removeEventListeners() - { - let canvas = this.canvas; - let presenter = this.presenter; - - canvas.removeEventListener("mousedown", this._onMouseDown, false); - canvas.removeEventListener("mouseup", this._onMouseUp, false); - canvas.removeEventListener("mousemove", this._onMouseMove, false); - canvas.removeEventListener("mouseover", this._onMouseOver, false); - canvas.removeEventListener("mouseout", this._onMouseOut, false); - canvas.removeEventListener("MozMousePixelScroll", this._onMozScroll, false); - canvas.removeEventListener("keydown", this._onKeyDown, false); - canvas.removeEventListener("keyup", this._onKeyUp, false); - canvas.removeEventListener("blur", this._onBlur, false); - - // Closing the tab would result in contentWindow being a dead object, - // so operations like removing event listeners won't work anymore. - if (presenter.contentWindow == presenter.chromeWindow.content) { - presenter.contentWindow.removeEventListener("resize", this._onResize, false); - } - }, - - /** - * Function called each frame, updating the visualization camera transforms. - * - * @param {Number} aTime - * total time passed since rendering started - * @param {Number} aDelta - * the current animation frame delta - */ - _update: function TVC__update(aTime, aDelta) - { - this._time = aTime; - this._coordinates = this.arcball.update(aDelta); - - this.presenter.setRotation(this._coordinates.rotation); - this.presenter.setTranslation(this._coordinates.translation); - }, - - /** - * Called once after every time a mouse button is pressed. - */ - _onMouseDown: function TVC__onMouseDown(e) - { - e.target.focus(); - e.preventDefault(); - e.stopPropagation(); - - if (this._time < MOUSE_INTRO_DELAY) { - return; - } - - // calculate x and y coordinates using using the client and target offset - let button = e.which; - this._downX = e.clientX - e.target.offsetLeft; - this._downY = e.clientY - e.target.offsetTop; - - this.arcball.mouseDown(this._downX, this._downY, button); - }, - - /** - * Called every time a mouse button is released. - */ - _onMouseUp: function TVC__onMouseUp(e) - { - e.preventDefault(); - e.stopPropagation(); - - if (this._time < MOUSE_INTRO_DELAY) { - return; - } - - // calculate x and y coordinates using using the client and target offset - let button = e.which; - let upX = e.clientX - e.target.offsetLeft; - let upY = e.clientY - e.target.offsetTop; - - // a click in Tilt is issued only when the mouse pointer stays in - // relatively the same position - if (Math.abs(this._downX - upX) < MOUSE_CLICK_THRESHOLD && - Math.abs(this._downY - upY) < MOUSE_CLICK_THRESHOLD) { - - this.presenter.highlightNodeAt(upX, upY); - } - - this.arcball.mouseUp(upX, upY, button); - }, - - /** - * Called every time the mouse moves. - */ - _onMouseMove: function TVC__onMouseMove(e) - { - e.preventDefault(); - e.stopPropagation(); - - if (this._time < MOUSE_INTRO_DELAY) { - return; - } - - // calculate x and y coordinates using using the client and target offset - let moveX = e.clientX - e.target.offsetLeft; - let moveY = e.clientY - e.target.offsetTop; - - this.arcball.mouseMove(moveX, moveY); - }, - - /** - * Called when the mouse leaves the visualization bounds. - */ - _onMouseOver: function TVC__onMouseOver(e) - { - e.preventDefault(); - e.stopPropagation(); - - this.arcball.mouseOver(); - }, - - /** - * Called when the mouse leaves the visualization bounds. - */ - _onMouseOut: function TVC__onMouseOut(e) - { - e.preventDefault(); - e.stopPropagation(); - - this.arcball.mouseOut(); - }, - - /** - * Called when the mouse wheel is used. - */ - _onMozScroll: function TVC__onMozScroll(e) - { - e.preventDefault(); - e.stopPropagation(); - - this.arcball.zoom(e.detail); - }, - - /** - * Called when a key is pressed. - */ - _onKeyDown: function TVC__onKeyDown(e) - { - let code = e.keyCode || e.which; - - if (!e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) { - e.preventDefault(); - e.stopPropagation(); - this.arcball.keyDown(code); - } else { - this.arcball.cancelKeyEvents(); - } - - if (e.keyCode === e.DOM_VK_ESCAPE) { - let {TiltManager} = require("devtools/client/tilt/tilt"); - let tilt = - TiltManager.getTiltForBrowser(this.presenter.chromeWindow); - e.preventDefault(); - e.stopPropagation(); - tilt.destroy(tilt.currentWindowId, true); - } - }, - - /** - * Called when a key is released. - */ - _onKeyUp: function TVC__onKeyUp(e) - { - let code = e.keyCode || e.which; - - if (code === e.DOM_VK_X) { - this.presenter.deleteNode(); - } - if (code === e.DOM_VK_F) { - let highlight = this.presenter._highlight; - let zoom = this.presenter.transforms.zoom; - - this.arcball.moveIntoView(vec3.lerp( - vec3.scale(highlight.v0, zoom, []), - vec3.scale(highlight.v1, zoom, []), 0.5)); - } - if (!e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey) { - e.preventDefault(); - e.stopPropagation(); - this.arcball.keyUp(code); - } - }, - - /** - * Called when the canvas looses focus. - */ - _onBlur: function TVC__onBlur(e) { - this.arcball.cancelKeyEvents(); - }, - - /** - * Called when the content window of the current browser is resized. - */ - _onResize: function TVC__onResize(e) - { - let zoom = this.presenter._getPageZoom(); - let width = e.target.innerWidth * zoom; - let height = e.target.innerHeight * zoom; - - this.arcball.resize(width, height); - }, - - /** - * Checks if this object was initialized properly. - * - * @return {Boolean} true if the object was initialized properly - */ - isInitialized: function TVC_isInitialized() - { - return this.arcball ? true : false; - }, - - /** - * Function called when this object is destroyed. - */ - _finalize: function TVC__finalize() - { - TiltUtils.destroyObject(this.arcball); - TiltUtils.destroyObject(this._coordinates); - - this.removeEventListeners(); - this.presenter.controller = null; - this.presenter._controllerUpdate = null; - } -}; - -/** - * This is a general purpose 3D rotation controller described by Ken Shoemake - * in the Graphics Interface ’92 Proceedings. It features good behavior - * easy implementation, cheap execution. - * - * @param {Window} aChromeWindow - * a reference to the top-level window - * @param {Number} aWidth - * the width of canvas - * @param {Number} aHeight - * the height of canvas - * @param {Number} aRadius - * optional, the radius of the arcball - * @param {Array} aInitialTrans - * optional, initial vector translation - * @param {Array} aInitialRot - * optional, initial quaternion rotation - */ -TiltVisualizer.Arcball = function TV_Arcball( - aChromeWindow, aWidth, aHeight, aRadius, aInitialTrans, aInitialRot) -{ - /** - * Save a reference to the top-level window to set/remove intervals. - */ - this.chromeWindow = aChromeWindow; - - /** - * Values retaining the current horizontal and vertical mouse coordinates. - */ - this._mousePress = vec3.create(); - this._mouseRelease = vec3.create(); - this._mouseMove = vec3.create(); - this._mouseLerp = vec3.create(); - this._mouseButton = -1; - - /** - * Object retaining the current pressed key codes. - */ - this._keyCode = {}; - - /** - * The vectors representing the mouse coordinates mapped on the arcball - * and their perpendicular converted from (x, y) to (x, y, z) at specific - * events like mousePressed and mouseDragged. - */ - this._startVec = vec3.create(); - this._endVec = vec3.create(); - this._pVec = vec3.create(); - - /** - * The corresponding rotation quaternions. - */ - this._lastRot = quat4.create(); - this._deltaRot = quat4.create(); - this._currentRot = quat4.create(aInitialRot); - - /** - * The current camera translation coordinates. - */ - this._lastTrans = vec3.create(); - this._deltaTrans = vec3.create(); - this._currentTrans = vec3.create(aInitialTrans); - this._zoomAmount = 0; - - /** - * Additional rotation and translation vectors. - */ - this._additionalRot = vec3.create(); - this._additionalTrans = vec3.create(); - this._deltaAdditionalRot = quat4.create(); - this._deltaAdditionalTrans = vec3.create(); - - // load the keys controlling the arcball - this._loadKeys(); - - // set the current dimensions of the arcball - this.resize(aWidth, aHeight, aRadius); -}; - -TiltVisualizer.Arcball.prototype = { - - /** - * Call this function whenever you need the updated rotation quaternion - * and the zoom amount. These values will be returned as "rotation" and - * "translation" properties inside an object. - * - * @param {Number} aDelta - * the current animation frame delta - * - * @return {Object} the rotation quaternion and the translation amount - */ - update: function TVA_update(aDelta) - { - let mousePress = this._mousePress; - let mouseRelease = this._mouseRelease; - let mouseMove = this._mouseMove; - let mouseLerp = this._mouseLerp; - let mouseButton = this._mouseButton; - - // smoothly update the mouse coordinates - mouseLerp[0] += (mouseMove[0] - mouseLerp[0]) * ARCBALL_SENSITIVITY; - mouseLerp[1] += (mouseMove[1] - mouseLerp[1]) * ARCBALL_SENSITIVITY; - - // cache the interpolated mouse coordinates - let x = mouseLerp[0]; - let y = mouseLerp[1]; - - // the smoothed arcball rotation may not be finished when the mouse is - // pressed again, so cancel the rotation if other events occur or the - // animation finishes - if (mouseButton === 3 || x === mouseRelease[0] && y === mouseRelease[1]) { - this._rotating = false; - } - - let startVec = this._startVec; - let endVec = this._endVec; - let pVec = this._pVec; - - let lastRot = this._lastRot; - let deltaRot = this._deltaRot; - let currentRot = this._currentRot; - - // left mouse button handles rotation - if (mouseButton === 1 || this._rotating) { - // the rotation doesn't stop immediately after the left mouse button is - // released, so add a flag to smoothly continue it until it ends - this._rotating = true; - - // find the sphere coordinates of the mouse positions - this._pointToSphere(x, y, this.width, this.height, this.radius, endVec); - - // compute the vector perpendicular to the start & end vectors - vec3.cross(startVec, endVec, pVec); - - // if the begin and end vectors don't coincide - if (vec3.length(pVec) > 0) { - deltaRot[0] = pVec[0]; - deltaRot[1] = pVec[1]; - deltaRot[2] = pVec[2]; - - // in the quaternion values, w is cosine (theta / 2), - // where theta is the rotation angle - deltaRot[3] = -vec3.dot(startVec, endVec); - } else { - // return an identity rotation quaternion - deltaRot[0] = 0; - deltaRot[1] = 0; - deltaRot[2] = 0; - deltaRot[3] = 1; - } - - // calculate the current rotation based on the mouse click events - quat4.multiply(lastRot, deltaRot, currentRot); - } else { - // save the current quaternion to stack rotations - quat4.set(currentRot, lastRot); - } - - let lastTrans = this._lastTrans; - let deltaTrans = this._deltaTrans; - let currentTrans = this._currentTrans; - - // right mouse button handles panning - if (mouseButton === 3) { - // calculate a delta translation between the new and old mouse position - // and save it to the current translation - deltaTrans[0] = mouseMove[0] - mousePress[0]; - deltaTrans[1] = mouseMove[1] - mousePress[1]; - - currentTrans[0] = lastTrans[0] + deltaTrans[0]; - currentTrans[1] = lastTrans[1] + deltaTrans[1]; - } else { - // save the current panning to stack translations - lastTrans[0] = currentTrans[0]; - lastTrans[1] = currentTrans[1]; - } - - let zoomAmount = this._zoomAmount; - let keyCode = this._keyCode; - - // mouse wheel handles zooming - deltaTrans[2] = (zoomAmount - currentTrans[2]) * ARCBALL_ZOOM_STEP; - currentTrans[2] += deltaTrans[2]; - - let additionalRot = this._additionalRot; - let additionalTrans = this._additionalTrans; - let deltaAdditionalRot = this._deltaAdditionalRot; - let deltaAdditionalTrans = this._deltaAdditionalTrans; - - let rotateKeys = this.rotateKeys; - let panKeys = this.panKeys; - let zoomKeys = this.zoomKeys; - let resetKey = this.resetKey; - - // handle additional rotation and translation by the keyboard - if (keyCode[rotateKeys.left]) { - additionalRot[0] -= ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP; - } - if (keyCode[rotateKeys.right]) { - additionalRot[0] += ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP; - } - if (keyCode[rotateKeys.up]) { - additionalRot[1] += ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP; - } - if (keyCode[rotateKeys.down]) { - additionalRot[1] -= ARCBALL_SENSITIVITY * ARCBALL_ROTATION_STEP; - } - if (keyCode[panKeys.left]) { - additionalTrans[0] -= ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP; - } - if (keyCode[panKeys.right]) { - additionalTrans[0] += ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP; - } - if (keyCode[panKeys.up]) { - additionalTrans[1] -= ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP; - } - if (keyCode[panKeys.down]) { - additionalTrans[1] += ARCBALL_SENSITIVITY * ARCBALL_TRANSLATION_STEP; - } - if (keyCode[zoomKeys["in"][0]] || - keyCode[zoomKeys["in"][1]] || - keyCode[zoomKeys["in"][2]]) { - this.zoom(-ARCBALL_TRANSLATION_STEP); - } - if (keyCode[zoomKeys["out"][0]] || - keyCode[zoomKeys["out"][1]]) { - this.zoom(ARCBALL_TRANSLATION_STEP); - } - if (keyCode[zoomKeys["unzoom"]]) { - this._zoomAmount = 0; - } - if (keyCode[resetKey]) { - this.reset(); - } - - // update the delta key rotations and translations - deltaAdditionalRot[0] += - (additionalRot[0] - deltaAdditionalRot[0]) * ARCBALL_SENSITIVITY; - deltaAdditionalRot[1] += - (additionalRot[1] - deltaAdditionalRot[1]) * ARCBALL_SENSITIVITY; - deltaAdditionalRot[2] += - (additionalRot[2] - deltaAdditionalRot[2]) * ARCBALL_SENSITIVITY; - - deltaAdditionalTrans[0] += - (additionalTrans[0] - deltaAdditionalTrans[0]) * ARCBALL_SENSITIVITY; - deltaAdditionalTrans[1] += - (additionalTrans[1] - deltaAdditionalTrans[1]) * ARCBALL_SENSITIVITY; - - // create an additional rotation based on the key events - quat4.fromEuler( - deltaAdditionalRot[0], - deltaAdditionalRot[1], - deltaAdditionalRot[2], deltaRot); - - // create an additional translation based on the key events - vec3.set([deltaAdditionalTrans[0], deltaAdditionalTrans[1], 0], deltaTrans); - - // handle the reset animation steps if necessary - if (this._resetInProgress) { - this._nextResetStep(aDelta || 1); - } - - // return the current rotation and translation - return { - rotation: quat4.multiply(deltaRot, currentRot), - translation: vec3.add(deltaTrans, currentTrans) - }; - }, - - /** - * Function handling the mouseDown event. - * Call this when the mouse was pressed. - * - * @param {Number} x - * the current horizontal coordinate of the mouse - * @param {Number} y - * the current vertical coordinate of the mouse - * @param {Number} aButton - * which mouse button was pressed - */ - mouseDown: function TVA_mouseDown(x, y, aButton) - { - // save the mouse down state and prepare for rotations or translations - this._mousePress[0] = x; - this._mousePress[1] = y; - this._mouseButton = aButton; - this._cancelReset(); - this._save(); - - // find the sphere coordinates of the mouse positions - this._pointToSphere( - x, y, this.width, this.height, this.radius, this._startVec); - - quat4.set(this._currentRot, this._lastRot); - }, - - /** - * Function handling the mouseUp event. - * Call this when a mouse button was released. - * - * @param {Number} x - * the current horizontal coordinate of the mouse - * @param {Number} y - * the current vertical coordinate of the mouse - */ - mouseUp: function TVA_mouseUp(x, y) - { - // save the mouse up state and prepare for rotations or translations - this._mouseRelease[0] = x; - this._mouseRelease[1] = y; - this._mouseButton = -1; - }, - - /** - * Function handling the mouseMove event. - * Call this when the mouse was moved. - * - * @param {Number} x - * the current horizontal coordinate of the mouse - * @param {Number} y - * the current vertical coordinate of the mouse - */ - mouseMove: function TVA_mouseMove(x, y) - { - // save the mouse move state and prepare for rotations or translations - // only if the mouse is pressed - if (this._mouseButton !== -1) { - this._mouseMove[0] = x; - this._mouseMove[1] = y; - } - }, - - /** - * Function handling the mouseOver event. - * Call this when the mouse enters the context bounds. - */ - mouseOver: function TVA_mouseOver() - { - // if the mouse just entered the parent bounds, stop the animation - this._mouseButton = -1; - }, - - /** - * Function handling the mouseOut event. - * Call this when the mouse leaves the context bounds. - */ - mouseOut: function TVA_mouseOut() - { - // if the mouse leaves the parent bounds, stop the animation - this._mouseButton = -1; - }, - - /** - * Function handling the arcball zoom amount. - * Call this, for example, when the mouse wheel was scrolled or zoom keys - * were pressed. - * - * @param {Number} aZoom - * the zoom direction and speed - */ - zoom: function TVA_zoom(aZoom) - { - this._cancelReset(); - this._zoomAmount = TiltMath.clamp(this._zoomAmount - aZoom, - ARCBALL_ZOOM_MIN, ARCBALL_ZOOM_MAX); - }, - - /** - * Function handling the keyDown event. - * Call this when a key was pressed. - * - * @param {Number} aCode - * the code corresponding to the key pressed - */ - keyDown: function TVA_keyDown(aCode) - { - this._cancelReset(); - this._keyCode[aCode] = true; - }, - - /** - * Function handling the keyUp event. - * Call this when a key was released. - * - * @param {Number} aCode - * the code corresponding to the key released - */ - keyUp: function TVA_keyUp(aCode) - { - this._keyCode[aCode] = false; - }, - - /** - * Maps the 2d coordinates of the mouse location to a 3d point on a sphere. - * - * @param {Number} x - * the current horizontal coordinate of the mouse - * @param {Number} y - * the current vertical coordinate of the mouse - * @param {Number} aWidth - * the width of canvas - * @param {Number} aHeight - * the height of canvas - * @param {Number} aRadius - * optional, the radius of the arcball - * @param {Array} aSphereVec - * a 3d vector to store the sphere coordinates - */ - _pointToSphere: function TVA__pointToSphere( - x, y, aWidth, aHeight, aRadius, aSphereVec) - { - // adjust point coords and scale down to range of [-1..1] - x = (x - aWidth * 0.5) / aRadius; - y = (y - aHeight * 0.5) / aRadius; - - // compute the square length of the vector to the point from the center - let normal = 0; - let sqlength = x * x + y * y; - - // if the point is mapped outside of the sphere - if (sqlength > 1) { - // calculate the normalization factor - normal = 1 / Math.sqrt(sqlength); - - // set the normalized vector (a point on the sphere) - aSphereVec[0] = x * normal; - aSphereVec[1] = y * normal; - aSphereVec[2] = 0; - } else { - // set the vector to a point mapped inside the sphere - aSphereVec[0] = x; - aSphereVec[1] = y; - aSphereVec[2] = Math.sqrt(1 - sqlength); - } - }, - - /** - * Cancels all pending transformations caused by key events. - */ - cancelKeyEvents: function TVA_cancelKeyEvents() - { - this._keyCode = {}; - }, - - /** - * Cancels all pending transformations caused by mouse events. - */ - cancelMouseEvents: function TVA_cancelMouseEvents() - { - this._rotating = false; - this._mouseButton = -1; - }, - - /** - * Incremental translation method. - * - * @param {Array} aTranslation - * the translation ammount on the [x, y] axis - */ - translate: function TVP_translate(aTranslation) - { - this._additionalTrans[0] += aTranslation[0]; - this._additionalTrans[1] += aTranslation[1]; - }, - - /** - * Incremental rotation method. - * - * @param {Array} aRotation - * the rotation ammount along the [x, y, z] axis - */ - rotate: function TVP_rotate(aRotation) - { - // explicitly rotate along y, x, z values because they're eulerian angles - this._additionalRot[0] += TiltMath.radians(aRotation[1]); - this._additionalRot[1] += TiltMath.radians(aRotation[0]); - this._additionalRot[2] += TiltMath.radians(aRotation[2]); - }, - - /** - * Moves a target point into view only if it's outside the currently visible - * area bounds (in which case it also resets any additional transforms). - * - * @param {Arary} aPoint - * the [x, y] point which should be brought into view - */ - moveIntoView: function TVA_moveIntoView(aPoint) { - let visiblePointX = -(this._currentTrans[0] + this._additionalTrans[0]); - let visiblePointY = -(this._currentTrans[1] + this._additionalTrans[1]); - - if (aPoint[1] - visiblePointY - MOVE_INTO_VIEW_ACCURACY > this.height || - aPoint[1] - visiblePointY + MOVE_INTO_VIEW_ACCURACY < 0 || - aPoint[0] - visiblePointX > this.width || - aPoint[0] - visiblePointX < 0) { - this.reset([0, -aPoint[1]]); - } - }, - - /** - * Resize this implementation to use different bounds. - * This function is automatically called when the arcball is created. - * - * @param {Number} newWidth - * the new width of canvas - * @param {Number} newHeight - * the new height of canvas - * @param {Number} newRadius - * optional, the new radius of the arcball - */ - resize: function TVA_resize(newWidth, newHeight, newRadius) - { - if (!newWidth || !newHeight) { - return; - } - - // set the new width, height and radius dimensions - this.width = newWidth; - this.height = newHeight; - this.radius = newRadius ? newRadius : Math.min(newWidth, newHeight); - this._save(); - }, - - /** - * Starts an animation resetting the arcball transformations to identity. - * - * @param {Array} aFinalTranslation - * optional, final vector translation - * @param {Array} aFinalRotation - * optional, final quaternion rotation - */ - reset: function TVA_reset(aFinalTranslation, aFinalRotation) - { - if ("function" === typeof this._onResetStart) { - this._onResetStart(); - this._onResetStart = null; - } - - this.cancelMouseEvents(); - this.cancelKeyEvents(); - this._cancelReset(); - - this._save(); - this._resetFinalTranslation = vec3.create(aFinalTranslation); - this._resetFinalRotation = quat4.create(aFinalRotation); - this._resetInProgress = true; - }, - - /** - * Cancels the current arcball reset animation if there is one. - */ - _cancelReset: function TVA__cancelReset() - { - if (this._resetInProgress) { - this._resetInProgress = false; - this._save(); - - if ("function" === typeof this._onResetFinish) { - this._onResetFinish(); - this._onResetFinish = null; - this._onResetStep = null; - } - } - }, - - /** - * Executes the next step in the arcball reset animation. - * - * @param {Number} aDelta - * the current animation frame delta - */ - _nextResetStep: function TVA__nextResetStep(aDelta) - { - // a very large animation frame delta (in case of seriously low framerate) - // would cause all the interpolations to become highly unstable - aDelta = TiltMath.clamp(aDelta, 1, 100); - - let fNearZero = EPSILON * EPSILON; - let fInterpLin = ARCBALL_RESET_LINEAR_FACTOR * aDelta; - let fInterpSph = ARCBALL_RESET_SPHERICAL_FACTOR; - let fTran = this._resetFinalTranslation; - let fRot = this._resetFinalRotation; - - let t = vec3.create(fTran); - let r = quat4.multiply(quat4.inverse(quat4.create(this._currentRot)), fRot); - - // reset the rotation quaternion and translation vector - vec3.lerp(this._currentTrans, t, fInterpLin); - quat4.slerp(this._currentRot, r, fInterpSph); - - // also reset any additional transforms by the keyboard or mouse - vec3.scale(this._additionalTrans, fInterpLin); - vec3.scale(this._additionalRot, fInterpLin); - this._zoomAmount *= fInterpLin; - - // clear the loop if the all values are very close to zero - if (vec3.length(vec3.subtract(this._lastRot, fRot, [])) < fNearZero && - vec3.length(vec3.subtract(this._deltaRot, fRot, [])) < fNearZero && - vec3.length(vec3.subtract(this._currentRot, fRot, [])) < fNearZero && - vec3.length(vec3.subtract(this._lastTrans, fTran, [])) < fNearZero && - vec3.length(vec3.subtract(this._deltaTrans, fTran, [])) < fNearZero && - vec3.length(vec3.subtract(this._currentTrans, fTran, [])) < fNearZero && - vec3.length(this._additionalRot) < fNearZero && - vec3.length(this._additionalTrans) < fNearZero) { - - this._cancelReset(); - } - - if ("function" === typeof this._onResetStep) { - this._onResetStep(); - } - }, - - /** - * Loads the keys to control this arcball. - */ - _loadKeys: function TVA__loadKeys() - { - this.rotateKeys = { - "up": Ci.nsIDOMKeyEvent["DOM_VK_W"], - "down": Ci.nsIDOMKeyEvent["DOM_VK_S"], - "left": Ci.nsIDOMKeyEvent["DOM_VK_A"], - "right": Ci.nsIDOMKeyEvent["DOM_VK_D"], - }; - this.panKeys = { - "up": Ci.nsIDOMKeyEvent["DOM_VK_UP"], - "down": Ci.nsIDOMKeyEvent["DOM_VK_DOWN"], - "left": Ci.nsIDOMKeyEvent["DOM_VK_LEFT"], - "right": Ci.nsIDOMKeyEvent["DOM_VK_RIGHT"], - }; - this.zoomKeys = { - "in": [ - Ci.nsIDOMKeyEvent["DOM_VK_I"], - Ci.nsIDOMKeyEvent["DOM_VK_ADD"], - Ci.nsIDOMKeyEvent["DOM_VK_EQUALS"], - ], - "out": [ - Ci.nsIDOMKeyEvent["DOM_VK_O"], - Ci.nsIDOMKeyEvent["DOM_VK_SUBTRACT"], - ], - "unzoom": Ci.nsIDOMKeyEvent["DOM_VK_0"] - }; - this.resetKey = Ci.nsIDOMKeyEvent["DOM_VK_R"]; - }, - - /** - * Saves the current arcball state, typically after resize or mouse events. - */ - _save: function TVA__save() - { - if (this._mousePress) { - let x = this._mousePress[0]; - let y = this._mousePress[1]; - - this._mouseMove[0] = x; - this._mouseMove[1] = y; - this._mouseRelease[0] = x; - this._mouseRelease[1] = y; - this._mouseLerp[0] = x; - this._mouseLerp[1] = y; - } - }, - - /** - * Function called when this object is destroyed. - */ - _finalize: function TVA__finalize() - { - this._cancelReset(); - } -}; - -/** - * Tilt configuration preferences. - */ -TiltVisualizer.Prefs = { - - /** - * Specifies if Tilt is enabled or not. - */ - get enabled() - { - return this._enabled; - }, - - set enabled(value) - { - TiltUtils.Preferences.set("enabled", "boolean", value); - this._enabled = value; - }, - - get introTransition() - { - return this._introTransition; - }, - - set introTransition(value) - { - TiltUtils.Preferences.set("intro_transition", "boolean", value); - this._introTransition = value; - }, - - get outroTransition() - { - return this._outroTransition; - }, - - set outroTransition(value) - { - TiltUtils.Preferences.set("outro_transition", "boolean", value); - this._outroTransition = value; - }, - - /** - * Loads the preferences. - */ - load: function TVC_load() - { - let prefs = TiltVisualizer.Prefs; - let get = TiltUtils.Preferences.get; - - prefs._enabled = get("enabled", "boolean"); - prefs._introTransition = get("intro_transition", "boolean"); - prefs._outroTransition = get("outro_transition", "boolean"); - } -}; - -/** - * A custom visualization shader. - * - * @param {Attribute} vertexPosition: the vertex position - * @param {Attribute} vertexTexCoord: texture coordinates used by the sampler - * @param {Attribute} vertexColor: specific [r, g, b] color for each vertex - * @param {Uniform} mvMatrix: the model view matrix - * @param {Uniform} projMatrix: the projection matrix - * @param {Uniform} sampler: the texture sampler to fetch the pixels from - */ -TiltVisualizer.MeshShader = { - - /** - * Vertex shader. - */ - vs: [ - "attribute vec3 vertexPosition;", - "attribute vec2 vertexTexCoord;", - "attribute vec3 vertexColor;", - - "uniform mat4 mvMatrix;", - "uniform mat4 projMatrix;", - - "varying vec2 texCoord;", - "varying vec3 color;", - - "void main() {", - " gl_Position = projMatrix * mvMatrix * vec4(vertexPosition, 1.0);", - " texCoord = vertexTexCoord;", - " color = vertexColor;", - "}" - ].join("\n"), - - /** - * Fragment shader. - */ - fs: [ - "#ifdef GL_ES", - "precision lowp float;", - "#endif", - - "uniform sampler2D sampler;", - - "varying vec2 texCoord;", - "varying vec3 color;", - - "void main() {", - " if (texCoord.x < 0.0) {", - " gl_FragColor = vec4(color, 1.0);", - " } else {", - " gl_FragColor = vec4(texture2D(sampler, texCoord).rgb, 1.0);", - " }", - "}" - ].join("\n") -}; diff --git a/devtools/client/tilt/tilt.js b/devtools/client/tilt/tilt.js deleted file mode 100644 index b976f9e28c90..000000000000 --- a/devtools/client/tilt/tilt.js +++ /dev/null @@ -1,264 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {Cu} = require("chrome"); - -var {TiltVisualizer} = require("devtools/client/tilt/tilt-visualizer"); -var TiltGL = require("devtools/client/tilt/tilt-gl"); -var TiltUtils = require("devtools/client/tilt/tilt-utils"); -var EventEmitter = require("devtools/shared/event-emitter"); -var Telemetry = require("devtools/client/shared/telemetry"); -var Services = require("Services"); - -// Tilt notifications dispatched through the nsIObserverService. -const TILT_NOTIFICATIONS = { - // Called early in the startup of a new tilt instance - STARTUP: "tilt-startup", - - // Fires when Tilt starts the initialization. - INITIALIZING: "tilt-initializing", - - // Fires immediately after initialization is complete. - // (when the canvas overlay is visible and the 3D mesh is completely created) - INITIALIZED: "tilt-initialized", - - // Fires immediately before the destruction is started. - DESTROYING: "tilt-destroying", - - // Fires immediately before the destruction is finished. - // (just before the canvas overlay is removed from its parent node) - BEFORE_DESTROYED: "tilt-before-destroyed", - - // Fires when Tilt is completely destroyed. - DESTROYED: "tilt-destroyed", - - // Fires when Tilt is shown (after a tab-switch). - SHOWN: "tilt-shown", - - // Fires when Tilt is hidden (after a tab-switch). - HIDDEN: "tilt-hidden", - - // Fires once Tilt highlights an element in the page. - HIGHLIGHTING: "tilt-highlighting", - - // Fires once Tilt stops highlighting any element. - UNHIGHLIGHTING: "tilt-unhighlighting", - - // Fires when a node is removed from the 3D mesh. - NODE_REMOVED: "tilt-node-removed" -}; - -var TiltManager = { - _instances: new WeakMap(), - getTiltForBrowser: function(aChromeWindow) - { - if (this._instances.has(aChromeWindow)) { - return this._instances.get(aChromeWindow); - } else { - let tilt = new Tilt(aChromeWindow); - this._instances.set(aChromeWindow, tilt); - return tilt; - } - }, -} - -exports.TiltManager = TiltManager; - -/** - * Object managing instances of the visualizer. - * - * @param {Window} aWindow - * the chrome window used by each visualizer instance - */ -function Tilt(aWindow) -{ - /** - * Save a reference to the top-level window. - */ - this.chromeWindow = aWindow; - - /** - * All the instances of TiltVisualizer. - */ - this.visualizers = {}; - - /** - * Shortcut for accessing notifications strings. - */ - this.NOTIFICATIONS = TILT_NOTIFICATIONS; - - EventEmitter.decorate(this); - - this.setup(); - - this._telemetry = new Telemetry(); -} - -Tilt.prototype = { - - /** - * Initializes a visualizer for the current tab or closes it if already open. - */ - toggle: function T_toggle() - { - let contentWindow = this.chromeWindow.gBrowser.selectedBrowser.contentWindow; - let id = this.currentWindowId; - let self = this; - - contentWindow.addEventListener("beforeunload", function onUnload() { - contentWindow.removeEventListener("beforeunload", onUnload, false); - self.destroy(id, true); - }, false); - - // if the visualizer for the current tab is already open, destroy it now - if (this.visualizers[id]) { - this.destroy(id, true); - this._telemetry.toolClosed("tilt"); - return; - } else { - this._telemetry.toolOpened("tilt"); - } - - // create a visualizer instance for the current tab - this.visualizers[id] = new TiltVisualizer({ - chromeWindow: this.chromeWindow, - contentWindow: contentWindow, - parentNode: this.chromeWindow.gBrowser.selectedBrowser.parentNode, - notifications: this.NOTIFICATIONS, - tab: this.chromeWindow.gBrowser.selectedTab - }); - - Services.obs.notifyObservers(contentWindow, TILT_NOTIFICATIONS.STARTUP, null); - this.visualizers[id].init(); - - // make sure the visualizer object was initialized properly - if (!this.visualizers[id].isInitialized()) { - this.destroy(id); - this.failureCallback && this.failureCallback(); - return; - } - - this.lastInstanceId = id; - // E10S: We should be using target here. See bug 1028234 - this.emit("change", { tab: this.chromeWindow.gBrowser.selectedTab }); - Services.obs.notifyObservers(contentWindow, TILT_NOTIFICATIONS.INITIALIZING, null); - }, - - /** - * Starts destroying a specific instance of the visualizer. - * - * @param {String} aId - * the identifier of the instance in the visualizers array - * @param {Boolean} aAnimateFlag - * optional, set to true to display a destruction transition - */ - destroy: function T_destroy(aId, aAnimateFlag) - { - // if the visualizer is destroyed or destroying, don't do anything - if (!this.visualizers[aId] || this._isDestroying) { - return; - } - this._isDestroying = true; - - let controller = this.visualizers[aId].controller; - let presenter = this.visualizers[aId].presenter; - - let content = presenter.contentWindow; - let pageXOffset = content.pageXOffset * presenter.transforms.zoom; - let pageYOffset = content.pageYOffset * presenter.transforms.zoom; - TiltUtils.setDocumentZoom(this.chromeWindow, presenter.transforms.zoom); - - // if we're not doing any outro animation, just finish destruction directly - if (!aAnimateFlag) { - this._finish(aId); - return; - } - - // otherwise, trigger the outro animation and notify necessary observers - Services.obs.notifyObservers(content, TILT_NOTIFICATIONS.DESTROYING, null); - - controller.removeEventListeners(); - controller.arcball.reset([-pageXOffset, -pageYOffset]); - presenter.executeDestruction(this._finish.bind(this, aId)); - }, - - /** - * Finishes detroying a specific instance of the visualizer. - * - * @param {String} aId - * the identifier of the instance in the visualizers array - */ - _finish: function T__finish(aId) - { - let contentWindow = this.visualizers[aId].presenter.contentWindow; - this.visualizers[aId].removeOverlay(); - this.visualizers[aId].cleanup(); - this.visualizers[aId] = null; - - this._isDestroying = false; - this.chromeWindow.gBrowser.selectedBrowser.focus(); - // E10S: We should be using target here. See bug 1028234 - this.emit("change", { tab: this.chromeWindow.gBrowser.selectedTab }); - Services.obs.notifyObservers(contentWindow, TILT_NOTIFICATIONS.DESTROYED, null); - }, - - /** - * Handles the event fired when a tab is selected. - */ - _onTabSelect: function T__onTabSelect() - { - if (this.visualizers[this.lastInstanceId]) { - let contentWindow = this.visualizers[this.lastInstanceId].presenter.contentWindow; - Services.obs.notifyObservers(contentWindow, TILT_NOTIFICATIONS.HIDDEN, null); - } - - if (this.currentInstance) { - let contentWindow = this.currentInstance.presenter.contentWindow; - Services.obs.notifyObservers(contentWindow, TILT_NOTIFICATIONS.SHOWN, null); - } - - this.lastInstanceId = this.currentWindowId; - }, - - /** - * Add the browser event listeners to handle state changes. - */ - setup: function T_setup() - { - // load the preferences from the devtools.tilt branch - TiltVisualizer.Prefs.load(); - - this.chromeWindow.gBrowser.tabContainer.addEventListener( - "TabSelect", this._onTabSelect.bind(this), false); - }, - - /** - * Returns true if this tool is enabled. - */ - get enabled() - { - return (TiltVisualizer.Prefs.enabled && - (TiltGL.isWebGLForceEnabled() || TiltGL.isWebGLSupported())); - }, - - /** - * Gets the ID of the current window object to identify the visualizer. - */ - get currentWindowId() - { - return TiltUtils.getWindowId( - this.chromeWindow.gBrowser.selectedBrowser.contentWindow); - }, - - /** - * Gets the visualizer instance for the current tab. - */ - get currentInstance() - { - return this.visualizers[this.currentWindowId]; - }, -}; diff --git a/devtools/shared/locales/en-US/gclicommands.properties b/devtools/shared/locales/en-US/gclicommands.properties index 07dc5539b78c..01d28bd09571 100644 --- a/devtools/shared/locales/en-US/gclicommands.properties +++ b/devtools/shared/locales/en-US/gclicommands.properties @@ -335,140 +335,6 @@ eyedropperManual=Open a panel that magnifies an area of page to inspect pixels a # tooltip of button in devtools toolbox which toggles the Eyedropper tool. eyedropperTooltip=Grab a color from the page -# LOCALIZATION NOTE (tiltDesc) A very short description of the 'tilt' -# command. See tiltManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltDesc=Visualize the webpage in 3D - -# LOCALIZATION NOTE (tiltManual) A fuller description of the 'tilt' -# command, displayed when the user asks for help on what it does. -tiltManual=Investigate the relationship between various parts of a webpage and their ancestors in a 3D environment - -# LOCALIZATION NOTE (tiltOpenDesc) A very short description of the 'tilt inspect' -# command. See tiltOpenManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltOpenDesc=Open the Inspector 3D view - -# LOCALIZATION NOTE (tiltOpenManual) A fuller description of the 'tilt translate' -# command, displayed when the user asks for help on what it does. -tiltOpenManual=Initialize the 3D page inspector and optionally highlight a node using a CSS selector - -# LOCALIZATION NOTE (tiltToggleTooltip) A string displayed as the -# tooltip of button in devtools toolbox which toggles Tilt 3D View. -tiltToggleTooltip=3D View - -# LOCALIZATION NOTE (tiltTranslateDesc) A very short description of the 'tilt translate' -# command. See tiltTranslateManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltTranslateDesc=Move the webpage mesh - -# LOCALIZATION NOTE (tiltTranslateManual) A fuller description of the 'tilt translate' -# command, displayed when the user asks for help on what it does. -tiltTranslateManual=Incrementally translate the webpage mesh in a certain direction - -# LOCALIZATION NOTE (tiltTranslateXDesc) A very short string to describe the -# 'x' parameter to the 'tilt translate' command, which is displayed in a dialog -# when the user is using this command. -tiltTranslateXDesc=X (pixels) - -# LOCALIZATION NOTE (tiltTranslateXManual) A fuller description of the 'x' -# parameter to the 'translate' command, displayed when the user asks for help -# on what it does. -tiltTranslateXManual=The amount in pixels to translate the webpage mesh on the X axis - -# LOCALIZATION NOTE (tiltTranslateYDesc) A very short string to describe the -# 'y' parameter to the 'tilt translate' command, which is displayed in a dialog -# when the user is using this command. -tiltTranslateYDesc=Y (pixels) - -# LOCALIZATION NOTE (tiltTranslateYManual) A fuller description of the 'y' -# parameter to the 'translate' command, displayed when the user asks for help -# on what it does. -tiltTranslateYManual=The amount in pixels to translate the webpage mesh on the Y axis - -# LOCALIZATION NOTE (tiltRotateDesc) A very short description of the 'tilt rotate' -# command. See tiltRotateManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltRotateDesc=Spin the webpage mesh - -# LOCALIZATION NOTE (tiltRotateManual) A fuller description of the 'tilt rotate' -# command, displayed when the user asks for help on what it does. -tiltRotateManual=Incrementally rotate the webpage mesh in a certain direction - -# LOCALIZATION NOTE (tiltRotateXDesc) A very short string to describe the -# 'x' parameter to the 'tilt rotate' command, which is displayed in a dialog -# when the user is using this command. -tiltRotateXDesc=X (degrees) - -# LOCALIZATION NOTE (tiltRotateXManual) A fuller description of the 'x' -# parameter to the 'rotate' command, displayed when the user asks for help -# on what it does. -tiltRotateXManual=The amount in degrees to rotate the webpage mesh along the X axis - -# LOCALIZATION NOTE (tiltRotateYDesc) A very short string to describe the -# 'y' parameter to the 'tilt rotate' command, which is displayed in a dialog -# when the user is using this command. -tiltRotateYDesc=Y (degrees) - -# LOCALIZATION NOTE (tiltRotateYManual) A fuller description of the 'y' -# parameter to the 'rotate' command, displayed when the user asks for help -# on what it does. -tiltRotateYManual=The amount in degrees to rotate the webpage mesh along the Y axis - -# LOCALIZATION NOTE (tiltRotateZDesc) A very short string to describe the -# 'z' parameter to the 'tilt rotate' command, which is displayed in a dialog -# when the user is using this command. -tiltRotateZDesc=Z (degrees) - -# LOCALIZATION NOTE (tiltRotateZManual) A fuller description of the 'z' -# parameter to the 'rotate' command, displayed when the user asks for help -# on what it does. -tiltRotateZManual=The amount in degrees to rotate the webpage mesh along the Z axis - -# LOCALIZATION NOTE (tiltZoomDesc) A very short description of the 'tilt zoom' -# command. See tiltZoomManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltZoomDesc=Move away or towards the webpage mesh - -# LOCALIZATION NOTE (tiltZoomManual) A fuller description of the 'tilt zoom' -# command, displayed when the user asks for help on what it does. -tiltZoomManual=Incrementally move the webpage mesh in a certain direction along the Z axis - -# LOCALIZATION NOTE (tiltZoomAmountDesc) A very short string to describe the -# 'zoom' parameter to the 'tilt zoom' command, which is displayed in a dialog -# when the user is using this command. -tiltZoomAmountDesc=Zoom (pixels) - -# LOCALIZATION NOTE (tiltZoomAmmuntManual) A fuller description of the 'zoom' -# parameter to the 'zoom' command, displayed when the user asks for help -# on what it does. -tiltZoomAmountManual=The amount in pixels to translate the webpage mesh along the Z axis - -# LOCALIZATION NOTE (tiltResetDesc) A very short description of the 'tilt reset' -# command. See tiltResetManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltResetDesc=Reset the translation, rotation and zoom - -# LOCALIZATION NOTE (tiltResetManual) A fuller description of the 'tilt reset' -# command, displayed when the user asks for help on what it does. -tiltResetManual=Resets any transformations applied to the webpage mesh modelview matrix - -# LOCALIZATION NOTE (tiltCloseDesc) A very short description of the 'tilt close' -# command. See tiltCloseManual for a fuller description of what it does. This -# string is designed to be shown in a menu alongside the command name, which -# is why it should be as short as possible. -tiltCloseDesc=Close the visualization if open - -# LOCALIZATION NOTE (tiltCloseManual) A fuller description of the 'tilt close' -# command, displayed when the user asks for help on what it does. -tiltCloseManual=Close the visualization and switch back to the Inspector's default highlighter - # LOCALIZATION NOTE (debuggerClosed) Used in the output of several commands # to explain that the debugger must be opened first. debuggerClosed=The debugger must be opened before using this command From a14277868f74215f48affadc72c23060ebdae663 Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Thu, 3 Mar 2016 13:22:54 +0000 Subject: [PATCH 04/55] Backed out changeset a951d792d9b0 (bug 1218977) for causing bug 1251843. MozReview-Commit-ID: 1UxgFere953 --HG-- extra : amend_source : 238d7fd51b39731b108e58f52585b5e305049c89 --- browser/themes/shared/customizableui/panelUIOverlay.inc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/browser/themes/shared/customizableui/panelUIOverlay.inc.css b/browser/themes/shared/customizableui/panelUIOverlay.inc.css index 34c31a8be467..425a9498e7a8 100644 --- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css +++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css @@ -198,7 +198,6 @@ panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .pan overflow: visible; } -.cui-widget-panel > .panel-arrowcontainer > .panel-arrowcontent, #PanelUI-popup > .panel-arrowcontainer > .panel-arrowcontent { overflow: hidden; } From a7c049fabef82c1f2842baca5060d6856d22a860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Thu, 3 Mar 2016 15:02:13 +0100 Subject: [PATCH 05/55] Bug 1253229 - Fix and enable browser_fullscreen-window-open.js for e10s. r=gijs --- browser/base/content/test/general/browser.ini | 2 +- .../general/browser_fullscreen-window-open.js | 46 +++++++------------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index dcfac57841ff..ed100a02856d 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -314,7 +314,7 @@ skip-if = true # browser_drag.js is disabled, as it needs to be updated for the [browser_findbarClose.js] [browser_focusonkeydown.js] [browser_fullscreen-window-open.js] -skip-if = buildapp == 'mulet' || e10s || os == "linux" # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly. Linux: Intermittent failures - bug 941575. +skip-if = buildapp == 'mulet' || os == "linux" # Linux: Intermittent failures - bug 941575. [browser_fxaccounts.js] support-files = fxa_profile_handler.sjs [browser_fxa_migrate.js] diff --git a/browser/base/content/test/general/browser_fullscreen-window-open.js b/browser/base/content/test/general/browser_fullscreen-window-open.js index e669434313da..722ab0c41106 100644 --- a/browser/base/content/test/general/browser_fullscreen-window-open.js +++ b/browser/base/content/test/general/browser_fullscreen-window-open.js @@ -16,19 +16,15 @@ function test () { Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, true); - let newTab = gBrowser.addTab(); + let newTab = gBrowser.addTab(gHttpTestRoot + TEST_FILE); gBrowser.selectedTab = newTab; - let gTestBrowser = gBrowser.selectedBrowser; - gTestBrowser.addEventListener("load", function onLoad(){ - gTestBrowser.removeEventListener("load", onLoad, true, true); - + whenTabLoaded(newTab, function () { // Enter browser fullscreen mode. BrowserFullScreen(); runNextTest(); - }, true, true); - gTestBrowser.contentWindow.location.href = gHttpTestRoot + TEST_FILE; + }); } registerCleanupFunction(function(){ @@ -202,11 +198,8 @@ function waitForTabOpen(aOptions) { gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true); let tab = aEvent.target; - tab.linkedBrowser.addEventListener("load", function onLoad(ev){ - let browser = ev.currentTarget; - browser.removeEventListener("load", onLoad, true, true); - - is(browser.contentWindow.document.title, message.title, + whenTabLoaded(tab, function () { + is(tab.linkedBrowser.contentTitle, message.title, "Opened Tab is expected: " + message.title); if (aOptions.successFn) { @@ -215,7 +208,7 @@ function waitForTabOpen(aOptions) { gBrowser.removeTab(tab); finalize(); - }, true, true); + }); } gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true); @@ -240,7 +233,7 @@ function waitForTabOpen(aOptions) { function waitForWindowOpen(aOptions) { let start = Date.now(); let message = aOptions.message; - let url = aOptions.url || getBrowserURL(); + let url = aOptions.url || "about:blank"; if (!message.title) { ok(false, "Can't get message.title"); @@ -258,33 +251,31 @@ function waitForWindowOpen(aOptions) { runNextTest(); }; - let listener = new WindowListener(message.title, url, { + let listener = new WindowListener(message.title, getBrowserURL(), { onSuccess: aOptions.successFn, onFinalize: onFinalize, }); Services.wm.addListener(listener); - const URI = aOptions.url || "about:blank"; - executeWindowOpenInContent({ - uri: URI, + uri: url, title: message.title, option: message.param, }); } function executeWindowOpenInContent(aParam) { - var testWindow = gBrowser.selectedBrowser.contentWindow; - var testElm = testWindow.document.getElementById("test"); - - testElm.setAttribute("data-test-param", JSON.stringify(aParam)); - EventUtils.synthesizeMouseAtCenter(testElm, {}, testWindow); + ContentTask.spawn(gBrowser.selectedBrowser, JSON.stringify(aParam), function* (dataTestParam) { + let testElm = content.document.getElementById("test"); + testElm.setAttribute("data-test-param", dataTestParam); + testElm.click(); + }); } function waitForWindowOpenFromChrome(aOptions) { let start = Date.now(); let message = aOptions.message; - let url = aOptions.url || getBrowserURL(); + let url = aOptions.url || "about:blank"; if (!message.title) { ok(false, "Can't get message.title"); @@ -302,16 +293,13 @@ function waitForWindowOpenFromChrome(aOptions) { runNextTest(); }; - let listener = new WindowListener(message.title, url, { + let listener = new WindowListener(message.title, getBrowserURL(), { onSuccess: aOptions.successFn, onFinalize: onFinalize, }); Services.wm.addListener(listener); - - const URI = aOptions.url || "about:blank"; - - let testWindow = window.open(URI, message.title, message.option); + let testWindow = window.open(url, message.title, message.option); } function WindowListener(aTitle, aUrl, aCallBackObj) { From 3d10357055aa4109f1b621d654fd45c79d5b5470 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Thu, 3 Mar 2016 09:54:05 -0500 Subject: [PATCH 06/55] Bug 1250323 - Don't hide overflow-y on the pseudo class panel r=pbro --- devtools/client/inspector/inspector.xul | 34 ++++++------ devtools/client/themes/computed.css | 9 ++-- devtools/client/themes/fonts.css | 4 ++ devtools/client/themes/rules.css | 70 +++++++++++++++---------- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/devtools/client/inspector/inspector.xul b/devtools/client/inspector/inspector.xul index 2bad1a82ea5c..9b9ccb2e36bf 100644 --- a/devtools/client/inspector/inspector.xul +++ b/devtools/client/inspector/inspector.xul @@ -193,21 +193,25 @@ - - - - + + + + + + + + + + - - + - @@ -215,7 +219,7 @@ - + - + .devtools-toolbar { + display: flex; +} + #browser-style-checkbox { /* Bug 1200073 - extra space before the browser styles checkbox so they aren't squished together in a small window. */ @@ -142,11 +146,6 @@ margin: 0 5px; } -#root .devtools-toolbar { - width: 100%; - display: flex; -} - .link { padding: 0 3px; cursor: pointer; diff --git a/devtools/client/themes/fonts.css b/devtools/client/themes/fonts.css index 64b6c5a73ca1..70cd4e4459eb 100644 --- a/devtools/client/themes/fonts.css +++ b/devtools/client/themes/fonts.css @@ -14,6 +14,10 @@ position: absolute; } +#sidebar-panel-fontinspector > .devtools-toolbar { + display: flex; +} + #font-container { overflow: auto; flex: auto; diff --git a/devtools/client/themes/rules.css b/devtools/client/themes/rules.css index 2e5088e0dbbe..fcecb788a035 100644 --- a/devtools/client/themes/rules.css +++ b/devtools/client/themes/rules.css @@ -13,6 +13,8 @@ --rule-filter-icon: url(images/magnifying-glass.png); } +/* Rule View Tabpanel */ + #sidebar-panel-ruleview { margin: 0; display: flex; @@ -24,6 +26,47 @@ position: absolute; } +/* Rule View Toolbar */ + +#ruleview-toolbar-container { + display: flex; + flex-direction: column; + height: auto; +} + +#ruleview-toolbar { + display: flex; + height: 23px; +} + +#ruleview-toolbar > .devtools-searchbox:first-child { + -moz-padding-start: 0px; +} + +#ruleview-command-toolbar { + display: flex; +} + +#pseudo-class-panel { + display: flex; + height: 24px; + overflow: hidden; + transition: height 150ms ease; +} + +#pseudo-class-panel[hidden] { + height: 0px; +} + +#pseudo-class-panel > label { + -moz-user-select: none; + flex-grow: 1; + display: flex; + align-items: center; +} + +/* Rule View Container */ + #ruleview-container { -moz-user-select: text; overflow: auto; @@ -36,33 +79,6 @@ transition: visibility 0.25s; } -.devtools-sidebar-toolbar { - display: flex; -} - -#pseudo-class-panel { - position: relative; - margin-top: -1px; - margin-bottom: -1px; - overflow-y: hidden; - max-height: 24px; - outline: 0 !important; - transition-property: max-height; - transition-duration: 150ms; - transition-timing-function: ease; -} - -#pseudo-class-panel[hidden] { - max-height: 0px; -} - -#pseudo-class-panel > label { - -moz-user-select: none; - flex-grow: 1; - display: flex; - align-items: center; -} - .ruleview-code { direction: ltr; } From 26c4b80f4ab86f37d477b02f70d8ceb1d9c179f0 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Thu, 3 Mar 2016 09:54:09 -0500 Subject: [PATCH 07/55] Bug 1252008 - Adjust the max-height of the media queries to make the Box model resizes properly r=pbro --- devtools/client/themes/layout.css | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/devtools/client/themes/layout.css b/devtools/client/themes/layout.css index 7d2c01c0ef57..bae505aaad30 100644 --- a/devtools/client/themes/layout.css +++ b/devtools/client/themes/layout.css @@ -4,6 +4,7 @@ #sidebar-panel-layoutview { display: block; + overflow: auto; } #layout-container { @@ -41,7 +42,7 @@ -moz-box-pack: end; } -@media (max-height: 228px) { +@media (max-height: 250px) { #layout-header { padding-top: 0; padding-bottom: 0; @@ -91,7 +92,7 @@ /* Respond to window size change by changing the size of the regions */ -@media (max-height: 228px) { +@media (max-height: 250px) { #layout-content { height: 18px; } @@ -227,7 +228,7 @@ /* Coordinates should be different when the window is small, because we make the regions smaller then */ -@media (max-height: 228px) { +@media (max-height: 250px) { .layout-padding.layout-top { top: 37px; } @@ -300,7 +301,7 @@ color: var(--theme-highlight-blue); } -@media (max-height: 228px) { +@media (max-height: 250px) { .layout-legend { margin: 2px 6px; } From aa8686e0d309eecbbf5447ea9dd4650ff3bda575 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Thu, 3 Mar 2016 09:54:41 -0500 Subject: [PATCH 08/55] Bug 1252640 - Fix overlapping borders in the ruleview-header r=pbro --- devtools/client/inspector/rules/rules.js | 27 +++++++++---------- .../test/browser_rules_pseudo-element_01.js | 18 ++++++------- devtools/client/themes/rules.css | 5 ++-- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/devtools/client/inspector/rules/rules.js b/devtools/client/inspector/rules/rules.js index 9f765cc65563..42fc39b401ba 100644 --- a/devtools/client/inspector/rules/rules.js +++ b/devtools/client/inspector/rules/rules.js @@ -1059,7 +1059,6 @@ CssRuleView.prototype = { createExpandableContainer: function(label, isPseudo = false) { let header = this.styleDocument.createElementNS(HTML_NS, "div"); header.className = this._getRuleViewHeaderClassName(true); - header.classList.add("show-expandable-container"); header.textContent = label; let twisty = this.styleDocument.createElementNS(HTML_NS, "span"); @@ -1071,20 +1070,21 @@ CssRuleView.prototype = { let container = this.styleDocument.createElementNS(HTML_NS, "div"); container.classList.add("ruleview-expandable-container"); + container.hidden = false; this.element.appendChild(container); header.addEventListener("dblclick", () => { - this._toggleContainerVisibility(twisty, header, isPseudo, + this._toggleContainerVisibility(twisty, container, isPseudo, !this.showPseudoElements); }, false); twisty.addEventListener("click", () => { - this._toggleContainerVisibility(twisty, header, isPseudo, + this._toggleContainerVisibility(twisty, container, isPseudo, !this.showPseudoElements); }, false); if (isPseudo) { - this._toggleContainerVisibility(twisty, header, isPseudo, + this._toggleContainerVisibility(twisty, container, isPseudo, this.showPseudoElements); } @@ -1095,15 +1095,16 @@ CssRuleView.prototype = { * Toggle the visibility of an expandable container * * @param {DOMNode} twisty - * clickable toggle DOM Node - * @param {DOMNode} header - * expandable container header DOM Node + * Clickable toggle DOM Node + * @param {DOMNode} container + * Expandable container DOM Node * @param {Boolean} isPseudo - * whether or not the container will hold pseudo element rules + * Whether or not the container will hold pseudo element rules * @param {Boolean} showPseudo - * whether or not pseudo element rules should be displayed + * Whether or not pseudo element rules should be displayed */ - _toggleContainerVisibility: function(twisty, header, isPseudo, showPseudo) { + _toggleContainerVisibility: function(twisty, container, isPseudo, + showPseudo) { let isOpen = twisty.getAttribute("open"); if (isPseudo) { @@ -1112,12 +1113,10 @@ CssRuleView.prototype = { Services.prefs.setBoolPref("devtools.inspector.show_pseudo_elements", this.showPseudoElements); - header.classList.toggle("show-expandable-container", - this.showPseudoElements); - + container.hidden = !this.showPseudoElements; isOpen = !this.showPseudoElements; } else { - header.classList.toggle("show-expandable-container"); + container.hidden = !container.hidden; } if (isOpen) { diff --git a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js index 1108574f9bc3..364acfbbbc48 100644 --- a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js +++ b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js @@ -40,23 +40,21 @@ function* testTopLeft(inspector, view) { info("Make sure that clicking on the twisty hides pseudo elements"); let expander = gutters[0].querySelector(".ruleview-expander"); - ok(view.element.firstChild.classList.contains("show-expandable-container"), - "Pseudo Elements are expanded"); + ok(!view.element.children[1].hidden, "Pseudo Elements are expanded"); expander.click(); - ok(!view.element.firstChild.classList.contains("show-expandable-container"), - "Pseudo Elements are collapsed by twisty"); + ok(view.element.children[1].hidden, + "Pseudo Elements are collapsed by twisty"); expander.click(); - ok(view.element.firstChild.classList.contains("show-expandable-container"), - "Pseudo Elements are expanded again"); + ok(!view.element.children[1].hidden, "Pseudo Elements are expanded again"); info("Make sure that dblclicking on the header container also toggles " + "the pseudo elements"); EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2}, view.styleWindow); - ok(!view.element.firstChild.classList.contains("show-expandable-container"), - "Pseudo Elements are collapsed by dblclicking"); + ok(view.element.children[1].hidden, + "Pseudo Elements are collapsed by dblclicking"); let elementRuleView = getRuleViewRuleEditor(view, 3); @@ -135,8 +133,8 @@ function* testTopRight(inspector, view) { expander.scrollIntoView(); expander.click(); - ok(view.element.firstChild.classList.contains("show-expandable-container"), - "Pseudo Elements are shown again after clicking twisty"); + ok(!view.element.children[1].hidden, + "Pseudo Elements are shown again after clicking twisty"); } function* testBottomRight(inspector, view) { diff --git a/devtools/client/themes/rules.css b/devtools/client/themes/rules.css index fcecb788a035..461efc8132e2 100644 --- a/devtools/client/themes/rules.css +++ b/devtools/client/themes/rules.css @@ -87,11 +87,11 @@ pointer-events: none; } -.ruleview-expandable-container { +.ruleview-expandable-container[hidden] { display: none; } -.show-expandable-container + .ruleview-expandable-container { +.ruleview-expandable-container { display: block; } @@ -151,6 +151,7 @@ vertical-align: middle; min-height: 1.5em; line-height: 1.5em; + margin-top: -1px; } :root[platform="win"] .ruleview-header, From bb3b08b6d83083affaf264bcb139113e2be8d55c Mon Sep 17 00:00:00 2001 From: Jan Keromnes Date: Thu, 3 Mar 2016 09:47:23 -0600 Subject: [PATCH 09/55] Bug 1239705 - Add a 'Start' button for service workers in about:debugging. r=ochameau --- .../client/aboutdebugging/aboutdebugging.css | 3 +- .../aboutdebugging/components/target.js | 15 +++- .../client/aboutdebugging/test/browser.ini | 1 + .../test/browser_service_workers_start.js | 85 +++++++++++++++++++ .../locales/en-US/aboutdebugging.properties | 1 + devtools/server/actors/worker.js | 19 +++++ devtools/server/moz.build | 1 + devtools/server/service-worker-child.js | 32 +++++++ 8 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 devtools/client/aboutdebugging/test/browser_service_workers_start.js create mode 100644 devtools/server/service-worker-child.js diff --git a/devtools/client/aboutdebugging/aboutdebugging.css b/devtools/client/aboutdebugging/aboutdebugging.css index 3493ad433167..929729a5bb27 100644 --- a/devtools/client/aboutdebugging/aboutdebugging.css +++ b/devtools/client/aboutdebugging/aboutdebugging.css @@ -14,6 +14,7 @@ h2, h3, h4 { button { padding-left: 20px; padding-right: 20px; + min-width: 100px; } /* Category tabs */ @@ -86,4 +87,4 @@ button { .addons-debugging-label { display: inline-block; margin: 0 5px 5px 0; -} \ No newline at end of file +} diff --git a/devtools/client/aboutdebugging/components/target.js b/devtools/client/aboutdebugging/components/target.js index 5ee32fbdcf9a..5e6f38f8bdde 100644 --- a/devtools/client/aboutdebugging/components/target.js +++ b/devtools/client/aboutdebugging/components/target.js @@ -51,7 +51,10 @@ module.exports = createClass({ onClick: this.debug, disabled: debugDisabled, }, Strings.GetStringFromName("debug")) : - null + dom.button({ + className: "start-button", + onClick: this.start + }, Strings.GetStringFromName("start")) ) ); }, @@ -89,6 +92,16 @@ module.exports = createClass({ } }, + start() { + let { client, target } = this.props; + if (target.type === "serviceworker" && !target.workerActor) { + client.request({ + to: target.registrationActor, + type: "start" + }); + } + }, + openWorkerToolbox(workerActor) { let { client } = this.props; client.attachWorker(workerActor, (response, workerClient) => { diff --git a/devtools/client/aboutdebugging/test/browser.ini b/devtools/client/aboutdebugging/test/browser.ini index 8c1d7f96746d..9c5e3be83887 100644 --- a/devtools/client/aboutdebugging/test/browser.ini +++ b/devtools/client/aboutdebugging/test/browser.ini @@ -15,4 +15,5 @@ support-files = [browser_addons_toggle_debug.js] [browser_service_workers.js] [browser_service_workers_push.js] +[browser_service_workers_start.js] [browser_service_workers_timeout.js] diff --git a/devtools/client/aboutdebugging/test/browser_service_workers_start.js b/devtools/client/aboutdebugging/test/browser_service_workers_start.js new file mode 100644 index 000000000000..1cd4741da422 --- /dev/null +++ b/devtools/client/aboutdebugging/test/browser_service_workers_start.js @@ -0,0 +1,85 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that clicking on the Start button next to a Service Worker works as +// intended in about:debugging. +// It should cause a worker to start running in a child process. + +// Service workers can't be loaded from chrome://, but http:// is ok with +// dom.serviceWorkers.testing.enabled turned on. +const HTTP_ROOT = CHROME_ROOT.replace( + "chrome://mochitests/content/", "http://mochi.test:8888/"); +const SERVICE_WORKER = HTTP_ROOT + "service-workers/empty-sw.js"; +const TAB_URL = HTTP_ROOT + "service-workers/empty-sw.html"; + +const SW_TIMEOUT = 1000; + +add_task(function* () { + info("Turn on workers via mochitest http."); + yield new Promise(done => { + let options = { "set": [ + // Accept workers from mochitest's http. + ["dom.serviceWorkers.testing.enabled", true], + // Reduce the timeout to accelerate service worker freezing + ["dom.serviceWorkers.idle_timeout", SW_TIMEOUT], + ["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT], + ]}; + SpecialPowers.pushPrefEnv(options, done); + }); + + let { tab, document } = yield openAboutDebugging("workers"); + + // Listen for mutations in the service-workers list. + let serviceWorkersElement = document.getElementById("service-workers"); + let onMutation = waitForMutation(serviceWorkersElement, { childList: true }); + + // Open a tab that registers an empty service worker. + let swTab = yield addTab(TAB_URL); + + // Wait for the service-workers list to update. + yield onMutation; + + // Check that the service worker appears in the UI. + assertHasTarget(true, document, "service-workers", SERVICE_WORKER); + + info("Ensure that the registration resolved before trying to interact with " + + "the service worker."); + yield waitForServiceWorkerRegistered(swTab); + ok(true, "Service worker registration resolved"); + + // Retrieve the Target element corresponding to the service worker. + let names = [...document.querySelectorAll("#service-workers .target-name")]; + let name = names.filter(element => element.textContent === SERVICE_WORKER)[0]; + ok(name, "Found the service worker in the list"); + let targetElement = name.parentNode.parentNode; + + // Check that there is a Debug button but not a Start button. + ok(targetElement.querySelector(".debug-button"), "Found its debug button"); + ok(!targetElement.querySelector(".start-button"), "No start button"); + + // Wait for the service worker to be killed due to inactivity. + yield waitForMutation(targetElement, { childList: true }); + + // We should now have a Start button but no Debug button. + let startBtn = targetElement.querySelector(".start-button"); + ok(startBtn, "Found its start button"); + ok(!targetElement.querySelector(".debug-button"), "No debug button"); + + // Click on the Start button and wait for the service worker to be back. + let onStarted = waitForMutation(targetElement, { childList: true }); + startBtn.click(); + yield onStarted; + + // Check that we have a Debug button but not a Start button again. + ok(targetElement.querySelector(".debug-button"), "Found its debug button"); + ok(!targetElement.querySelector(".start-button"), "No start button"); + + // Finally, unregister the service worker itself. + yield unregisterServiceWorker(swTab); + ok(true, "Service worker registration unregistered"); + + yield removeTab(swTab); + yield closeAboutDebugging(tab); +}); diff --git a/devtools/client/locales/en-US/aboutdebugging.properties b/devtools/client/locales/en-US/aboutdebugging.properties index f442177b004a..9030650a2dc8 100644 --- a/devtools/client/locales/en-US/aboutdebugging.properties +++ b/devtools/client/locales/en-US/aboutdebugging.properties @@ -4,6 +4,7 @@ debug = Debug push = Push +start = Start addons = Add-ons addonDebugging.label = Enable add-on debugging diff --git a/devtools/server/actors/worker.js b/devtools/server/actors/worker.js index f0816734f832..6a47a0992343 100644 --- a/devtools/server/actors/worker.js +++ b/devtools/server/actors/worker.js @@ -2,6 +2,7 @@ var { Ci, Cu } = require("chrome"); var { DebuggerServer } = require("devtools/server/main"); +var Services = require("Services"); const protocol = require("devtools/server/protocol"); const { Arg, method, RetVal } = protocol; @@ -303,6 +304,9 @@ WorkerActorList.prototype = { exports.WorkerActorList = WorkerActorList; +// Lazily load the service-worker-child.js process script only once. +let _serviceWorkerProcessScriptLoaded = false; + let ServiceWorkerRegistrationActor = protocol.ActorClass({ typeName: "serviceWorkerRegistration", @@ -323,6 +327,21 @@ let ServiceWorkerRegistrationActor = protocol.ActorClass({ }; }, + start: method(function() { + if (!_serviceWorkerProcessScriptLoaded) { + Services.ppmm.loadProcessScript( + "resource://devtools/server/service-worker-child.js", true); + _serviceWorkerProcessScriptLoaded = true; + } + Services.ppmm.broadcastAsyncMessage("serviceWorkerRegistration:start", { + scope: this._registration.scope + }); + return { type: "started" }; + }, { + request: {}, + response: RetVal("json") + }), + }); function ServiceWorkerRegistrationActorList(conn) { diff --git a/devtools/server/moz.build b/devtools/server/moz.build index 5433d110ef22..b828b60bcef2 100644 --- a/devtools/server/moz.build +++ b/devtools/server/moz.build @@ -35,6 +35,7 @@ DevToolsModules( 'main.js', 'primitive.js', 'protocol.js', + 'service-worker-child.js', 'worker.js' ) diff --git a/devtools/server/service-worker-child.js b/devtools/server/service-worker-child.js new file mode 100644 index 000000000000..e3a27ab10dfe --- /dev/null +++ b/devtools/server/service-worker-child.js @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +let { classes: Cc, interfaces: Ci, utils: Cu } = Components; +let swm = Cc["@mozilla.org/serviceworkers/manager;1"]. + getService(Ci.nsIServiceWorkerManager); + +addMessageListener("serviceWorkerRegistration:start", message => { + let { data } = message; + let array = swm.getAllRegistrations(); + + // Find the service worker registration with the desired scope. + for (let i = 0; i < array.length; i++) { + let registration = + array.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo); + // XXX: In some rare cases, `registration.activeWorker` can be null for a + // brief moment (e.g. while the service worker is first installing, or if + // there was an unhandled exception during install that will cause the + // registration to be removed). We can't do much about it here, simply + // ignore these cases. + if (registration.scope === data.scope && registration.activeWorker) { + // Briefly attaching a debugger to the active service worker will cause + // it to start running. + registration.activeWorker.attachDebugger(); + registration.activeWorker.detachDebugger(); + return; + } + } +}); From ed60aaa7d61ce340d8509867f7a44a9b4bba4adf Mon Sep 17 00:00:00 2001 From: Jan Keromnes Date: Thu, 3 Mar 2016 09:47:59 -0600 Subject: [PATCH 10/55] Bug 1239317 - Add a Service Workers entry to the Web Developer menu. r=jryans --- browser/base/content/browser-menubar.inc | 3 +++ browser/base/content/browser-sets.inc | 4 ++++ browser/locales/en-US/chrome/browser/browser.dtd | 3 +++ devtools/client/aboutdebugging/aboutdebugging.xhtml | 2 +- devtools/client/framework/devtools-browser.js | 9 +++++++++ devtools/client/framework/gDevTools.jsm | 3 +++ devtools/client/locales/en-US/aboutdebugging.dtd | 2 +- 7 files changed, 24 insertions(+), 2 deletions(-) diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc index f6c2c16ae694..8575fba651b6 100644 --- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -554,6 +554,9 @@ + diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc index 9f73362ce97b..4e6f8ffa6308 100644 --- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -107,6 +107,7 @@