From 7624030fbf5cb7f333c73b84496136967b39dfec Mon Sep 17 00:00:00 2001 From: Roy Tam Date: Fri, 4 Sep 2020 21:16:47 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1055181 - CSS Filter Tooltip; r=pbrosset (327b035a7) - Bug 1137238 - Fix toolboxes when switching between apps in WebIDE. r=jryans (1a333bdfa) - Bug 1138939 - Notify when WebIDE has finished initializing so that Valence can register runtime scanners. r=ochameau (7fe61c384) - Don't let WebIDE break when trying to debug Chrome settings (bug 1134619). r=ochameau (4a18f048e) - fix imports since devtools are in a different path compared to FF (15c2a1e70) - port bits of Bug 916804 - Telemetry for WebIDE. (cf5b49ca7) - Bug 1042859 - Ignore host port when fetching cookies with the gcli cookie command. r=pbrosset (1e6217f76) - fix include path (6efaacd7a) - Bug 1128988 - runAt support for commands/converters; r=bgrins (bed6cb594) - Bug 1143027 - The performance tool tab highlights during a recording. r=vp (e1f310e2d) - missing pieces of Bug 1141817 - Followup to fix additional intermittents and Bug 1142748 - Fix the 'Protocol error (unknownError) (b27da36af) - Bug 1159480 - Pull out actor-specific logic from Performance Front. r=vp (9c253604b) - Bug 1156499 - Disable all non-profiler/fps components in the performance tools when in aurora, for 40.0 release. r=vp (041a0fa34) - Bug 1159052 - Performance recording should stop rendering and recording as soon as the recording stops. r=vp (2a9f093b4) - Bug 114187 - Add getBufferInfo to devtools profiler actor. r=fitzgen (00496e8e4) - Bug 1145187 - Implement polling for buffer status on performance actor facades. r=vp (ae2cbac27) - Bug 1082695 - Simplify the record start/stop time buttons, and more cleanly render the console.profile notifications during a console recording. r=vp (dfe9a9b26) - Bug 1160900 - Display buffer status while recording a profile. r=vp (c3d302a62) - Bug 1154115 - Add adapter that deduplicates old, undeduplicated profiles in the frontend. (r=jsantell,vporof) (aa1bd6769) - Bug 1160696 - Display MIRTypes in the JIT optimizations side pane as "Site : MIRType". (r=jsantell) (beccaed3d) - Bug 1154115 - Make the memory stuff in the performance devtool synthesize the new profiler JSON format. (r=jsantell) (685e3a576) - Bug 1154115 - Fix nsIProfiler xpcshell tests to use the new profiler JSON format. (r=me) (da2a18c89) - Bug 1151526 - Do not display optimization data for meta-platform frames in the profiler. r=vporof (d4cc514ca) - Bug 1154115 - Fix devtools tests to use the new profiler JSON format. (r=jsantell) (61a9064ce) - Bug 1126432: Set preference toggle to switch to new WebIDE project listing layout r=jryans (825831eeb) - Bug 1130084 - Avoid spurious connection errors even on success. r=past (1911930b6) - missing bits of Bug 1069552 - Add WebIDE scanner / runtime API. (773111b87) - Bug 1130084 - Allow runtimes to take infinite time to connect. r=past (a1482c500) - Bug 1025311 - Add telemetry for canvas debugger. r=vp,miker (d2f8d51f2) - Bug 1134778 - Consolidate usages of view sourcing in tools with a source-utils module. r=vp,jryans (1432dfac1) - Bug 1167230 - Use nsCString instead of std::string in FrameKey in the profiler. (r=mstange) (9a3d84b86) - Bug 1166492 - Handle huge strings in the profile JSON writer. (r=mstange) (3d6f90062) - Bug 1166492 - Remove dead code in the ProfileBuffer and ThreadProfile. (r=mstange) (cc8e81dd3) - Bug 1166492 - Return UniquePtr from profiler_get_profile to avoid double copying. (r=mstange) (f9d58d5cf) - Bug 1167230 - Don't pack ProfileEntry on ARM. r=shu (b6f920dd3) - Bug 1168784 - Part 1: Fix the script merging profiles to handle new profiler JSON format. r=benwa (dd1008084) - Bug 1090949 - Add `nextTick()` to `lazyIframeIsLoaded()` in WebIDE tests. r=ochameau (94bf972da) - Bug 1143028 - Make AppMan reinitable; update tab list when sidebars disabled. r=past (1020f8306) - Bug 1146542 - Clean up and describe app-manager events. r=ochameau (cc4bcadf5) - Bug 1146542 - Restore tab list changes for non-sidebar case. r=ochameau (531b70e41) - Bug 1149820 - Restore WebIDE project auto select. r=ochameau (d0526612a) - Bug 1135018 - Move getjson from webide/ to shared/. r=jryans (9e405c1bf) - Bug 1135018 - Make devices.js use a CDN. r=ochameau (16adb49c4) - Bug 1090949 - Make WebIDE's Firefox OS Simulators configurable. r=ochameau (354331a6e) - Bug 1157201 - Prevent exception while hovering the rule-view. r=pbrosset (4ec81d85b) --- browser/app/profile/palemoon.js | 14 + browser/devtools/definitions.js | 410 ++++++++++ browser/devtools/main.js | 430 +---------- browser/devtools/moz.build | 1 + ...owser_console_addonsdk_loader_exception.js | 90 +++ .../browser_console_error_source_click.js | 73 ++ browser/themes/linux/jar.mn | 3 + browser/themes/osx/jar.mn | 3 + browser/themes/shared/devtools/images/add.svg | 3 + .../shared/devtools/images/filter-swatch.svg | 17 + .../devtools/images/tool-profiler-active.svg | 14 + browser/themes/windows/jar.mn | 3 + dom/ipc/ContentChild.cpp | 5 +- dom/plugins/ipc/PluginModuleChild.cpp | 5 +- modules/libpref/init/all.js | 6 + toolkit/commonjs/sdk/panel/utils.js | 1 + toolkit/components/telemetry/Histograms.json | 83 +- toolkit/devtools/Loader.jsm | 3 + toolkit/devtools/canvasdebugger/callslist.js | 21 +- .../devtools/canvasdebugger/canvasdebugger.js | 32 +- .../devtools/canvasdebugger/snapshotslist.js | 4 +- toolkit/devtools/client/connection-manager.js | 12 +- .../devtools/commandline/commands-index.js | 135 +++- .../commandline/test/browser_cmd_addon.js | 2 +- .../test/browser_cmd_appcache_invalid.js | 2 +- .../test/browser_cmd_appcache_valid.js | 2 +- .../commandline/test/browser_cmd_calllog.js | 2 +- .../test/browser_cmd_calllog_chrome.js | 2 +- .../commandline/test/browser_cmd_commands.js | 4 +- .../test/browser_cmd_csscoverage_startstop.js | 13 +- .../commandline/test/browser_cmd_jsb.js | 7 +- .../commandline/test/browser_cmd_media.js | 2 +- .../test/browser_cmd_pagemod_export.js | 8 +- .../commandline/test/browser_cmd_pref1.js | 2 +- .../commandline/test/browser_cmd_pref2.js | 2 +- .../commandline/test/browser_cmd_pref3.js | 2 +- .../test/browser_cmd_screenshot.js | 7 +- .../commandline/test/browser_cmd_settings.js | 14 +- .../commandline/test/browser_gcli_async.js | 24 +- .../commandline/test/browser_gcli_canon.js | 42 +- .../commandline/test/browser_gcli_cli1.js | 22 +- .../commandline/test/browser_gcli_cli2.js | 57 +- .../test/browser_gcli_completion1.js | 23 +- .../test/browser_gcli_completion2.js | 22 +- .../commandline/test/browser_gcli_context.js | 21 +- .../commandline/test/browser_gcli_date.js | 37 +- .../commandline/test/browser_gcli_exec.js | 121 ++- .../commandline/test/browser_gcli_fail.js | 21 +- .../commandline/test/browser_gcli_file.js | 26 +- .../test/browser_gcli_fileparser.js | 21 +- .../test/browser_gcli_filesystem.js | 21 +- .../commandline/test/browser_gcli_focus.js | 21 +- .../commandline/test/browser_gcli_history.js | 21 +- .../test/browser_gcli_incomplete.js | 21 +- .../commandline/test/browser_gcli_inputter.js | 23 +- .../commandline/test/browser_gcli_intro.js | 22 +- .../commandline/test/browser_gcli_js.js | 62 +- .../test/browser_gcli_keyboard1.js | 46 +- .../test/browser_gcli_keyboard2.js | 21 +- .../test/browser_gcli_keyboard3.js | 21 +- .../test/browser_gcli_keyboard4.js | 21 +- .../test/browser_gcli_keyboard5.js | 21 +- .../test/browser_gcli_keyboard6.js | 21 +- .../commandline/test/browser_gcli_menu.js | 21 +- .../commandline/test/browser_gcli_node.js | 98 +-- .../commandline/test/browser_gcli_pref1.js | 26 +- .../commandline/test/browser_gcli_pref2.js | 38 +- .../commandline/test/browser_gcli_remotews.js | 33 +- .../test/browser_gcli_remotexhr.js | 33 +- .../commandline/test/browser_gcli_resource.js | 96 +-- .../commandline/test/browser_gcli_short.js | 21 +- .../commandline/test/browser_gcli_spell.js | 21 +- .../commandline/test/browser_gcli_split.js | 21 +- .../commandline/test/browser_gcli_string.js | 21 +- .../commandline/test/browser_gcli_tokenize.js | 21 +- .../commandline/test/browser_gcli_tooltip.js | 26 +- .../commandline/test/browser_gcli_types.js | 58 +- .../commandline/test/browser_gcli_union.js | 25 +- .../commandline/test/browser_gcli_url.js | 23 +- toolkit/devtools/commandline/test/helpers.js | 167 +++- .../devtools/commandline/test/mockCommands.js | 106 ++- .../devtools/debugger/debugger-commands.js | 104 ++- toolkit/devtools/eyedropper/commands.js | 13 +- toolkit/devtools/framework/gDevTools.jsm | 5 + toolkit/devtools/framework/test/browser.ini | 8 +- .../browser_toolbox_tool_remote_reopen.js | 4 + .../test/browser_toolbox_view_source_01.js | 38 + .../test/browser_toolbox_view_source_02.js | 46 ++ .../test/browser_toolbox_view_source_03.js | 38 + .../test/browser_toolbox_view_source_04.js | 37 + toolkit/devtools/framework/test/code_math.js | 4 + .../framework/test/doc_viewsource.html | 13 + toolkit/devtools/framework/test/head.js | 47 ++ toolkit/devtools/framework/toolbox.js | 57 +- toolkit/devtools/framework/toolbox.xul | 3 + toolkit/devtools/gcli/Templater.jsm | 56 +- toolkit/devtools/gcli/commands/addon.js | 84 +- toolkit/devtools/gcli/commands/appcache.js | 55 +- toolkit/devtools/gcli/commands/calllog.js | 49 +- toolkit/devtools/gcli/commands/cmd.js | 19 +- toolkit/devtools/gcli/commands/cookie.js | 80 +- toolkit/devtools/gcli/commands/csscoverage.js | 13 +- toolkit/devtools/gcli/commands/folder.js | 20 +- toolkit/devtools/gcli/commands/highlight.js | 58 +- toolkit/devtools/gcli/commands/inject.js | 14 +- toolkit/devtools/gcli/commands/jsb.js | 46 +- toolkit/devtools/gcli/commands/listen.js | 16 +- toolkit/devtools/gcli/commands/media.js | 16 +- toolkit/devtools/gcli/commands/pagemod.js | 62 +- .../devtools/gcli/commands/paintflashing.js | 172 +++-- toolkit/devtools/gcli/commands/qsa.js | 6 +- toolkit/devtools/gcli/commands/restart.js | 16 +- toolkit/devtools/gcli/commands/rulers.js | 7 +- toolkit/devtools/gcli/commands/screenshot.js | 641 ++++++++++------ toolkit/devtools/gcli/commands/tools.js | 31 +- toolkit/devtools/gcli/moz.build | 7 +- .../gcli/source/docs/writing-commands.md | 3 +- .../gcli/source/docs/writing-types.md | 8 +- toolkit/devtools/gcli/source/lib/gcli/api.js | 217 ------ toolkit/devtools/gcli/source/lib/gcli/cli.js | 80 +- .../gcli/source/lib/gcli/commands/clear.js | 1 + .../gcli/source/lib/gcli/commands/commands.js | 69 +- .../gcli/source/lib/gcli/commands/connect.js | 40 +- .../gcli/source/lib/gcli/commands/global.js | 1 + .../gcli/source/lib/gcli/commands/help.js | 1 + .../gcli/source/lib/gcli/commands/mocks.js | 3 + .../gcli/source/lib/gcli/commands/pref.js | 3 + .../gcli/source/lib/gcli/commands/preflist.js | 22 +- .../gcli/source/lib/gcli/commands/test.js | 4 +- .../source/lib/gcli/connectors/connectors.js | 13 +- .../gcli/source/lib/gcli/connectors/index.js | 185 ----- .../source/lib/gcli/connectors/protocol.js | 56 -- .../gcli/source/lib/gcli/connectors/rdp.js | 145 ---- .../source/lib/gcli/connectors/remoted.js | 275 ------- .../gcli/source/lib/gcli/converters/basic.js | 19 + .../source/lib/gcli/converters/converters.js | 20 +- .../gcli/source/lib/gcli/fields/fields.js | 7 + .../gcli/source/lib/gcli/fields/selection.js | 8 +- .../devtools/gcli/source/lib/gcli/index.js | 148 ---- .../gcli/source/lib/gcli/languages/command.js | 14 +- .../source/lib/gcli/languages/javascript.js | 7 +- .../source/lib/gcli/languages/languages.js | 12 +- .../gcli/source/lib/gcli/mozui/ffdisplay.js | 237 ------ .../gcli/source/lib/gcli/mozui/inputter.js | 21 +- .../gcli/source/lib/gcli/mozui/tooltip.js | 9 +- .../devtools/gcli/source/lib/gcli/settings.js | 1 - .../devtools/gcli/source/lib/gcli/system.js | 371 +++++++++ .../gcli/source/lib/gcli/types/date.js | 25 +- .../gcli/source/lib/gcli/types/delegate.js | 85 ++- .../gcli/source/lib/gcli/types/javascript.js | 42 +- .../gcli/source/lib/gcli/types/node.js | 80 +- .../gcli/source/lib/gcli/types/number.js | 34 +- .../gcli/source/lib/gcli/types/resource.js | 60 +- .../gcli/source/lib/gcli/types/selection.js | 94 ++- .../gcli/source/lib/gcli/types/setting.js | 3 + .../gcli/source/lib/gcli/types/types.js | 20 +- .../gcli/source/lib/gcli/types/url.js | 2 +- .../devtools/gcli/source/lib/gcli/ui/menu.js | 21 +- .../gcli/source/lib/gcli/util/host.js | 2 +- .../gcli/source/lib/gcli/util/promise.js | 93 +-- .../gcli/source/lib/gcli/util/util.js | 52 +- .../devtools/inspector/inspector-commands.js | 12 +- toolkit/devtools/inspector/inspector-panel.js | 7 - toolkit/devtools/inspector/inspector.xul | 3 - toolkit/devtools/jar.mn | 2 + toolkit/devtools/output-parser.js | 27 + .../devtools/performance/modules/actors.js | 384 ++++++++++ .../performance/modules/compatibility.js | 142 ++-- toolkit/devtools/performance/modules/front.js | 415 ++++------ .../devtools/performance/modules/graphs.js | 31 +- toolkit/devtools/performance/modules/io.js | 3 + .../performance/modules/recording-model.js | 76 +- .../performance/modules/recording-utils.js | 447 ++++++++++- toolkit/devtools/performance/moz.build | 1 + toolkit/devtools/performance/panel.js | 16 +- .../performance/performance-controller.js | 115 +-- .../devtools/performance/performance-view.js | 137 +++- toolkit/devtools/performance/performance.xul | 45 +- toolkit/devtools/performance/test/browser.ini | 13 +- .../browser_perf-allocations-to-samples.js | 93 ++- .../test/browser_perf-compatibility-02.js | 7 +- .../test/browser_perf-compatibility-04.js | 7 +- .../test/browser_perf-compatibility-05.js | 11 +- .../test/browser_perf-compatibility-06.js | 32 + .../test/browser_perf-compatibility-07.js | 29 + .../test/browser_perf-console-record-01.js | 4 +- .../test/browser_perf-console-record-02.js | 8 +- .../test/browser_perf-console-record-03.js | 8 +- .../test/browser_perf-data-massaging-01.js | 9 +- .../test/browser_perf-data-samples.js | 7 +- .../test/browser_perf-events-calltree.js | 79 +- .../test/browser_perf-highlighted.js | 48 ++ .../test/browser_perf-jit-model-01.js | 135 ++-- .../test/browser_perf-jit-model-02.js | 135 +++- .../test/browser_perf-jit-view-01.js | 224 ++++-- .../test/browser_perf-jit-view-02.js | 165 ++++ .../test/browser_perf-jump-to-debugger-01.js | 27 - .../test/browser_perf-jump-to-debugger-02.js | 41 - ..._perf-options-flatten-tree-recursion-01.js | 18 +- ..._perf-options-flatten-tree-recursion-02.js | 24 +- .../test/browser_perf-recording-model-01.js | 62 ++ .../test/browser_perf-recording-model-02.js | 43 ++ .../test/browser_perf-recording-notices-03.js | 74 ++ .../test/browser_perf-recording-notices-04.js | 32 + .../test/browser_perf-shared-connection-02.js | 2 +- .../test/browser_profiler-frame-utils-01.js | 95 +++ .../test/browser_profiler_tree-frame-node.js | 75 +- .../test/browser_profiler_tree-model-01.js | 207 ++--- .../test/browser_profiler_tree-model-02.js | 30 +- .../test/browser_profiler_tree-model-03.js | 55 +- .../test/browser_profiler_tree-model-04.js | 48 +- .../test/browser_profiler_tree-model-05.js | 40 +- .../test/browser_profiler_tree-model-06.js | 214 ++++-- .../test/browser_profiler_tree-model-07.js | 32 +- .../test/browser_profiler_tree-view-01.js | 8 +- .../test/browser_profiler_tree-view-02.js | 8 +- .../test/browser_profiler_tree-view-03.js | 8 +- .../test/browser_profiler_tree-view-04.js | 8 +- .../test/browser_profiler_tree-view-05.js | 8 +- .../test/browser_profiler_tree-view-06.js | 8 +- .../test/browser_profiler_tree-view-07.js | 8 +- .../test/browser_profiler_tree-view-08.js | 8 +- .../performance/test/browser_retro-test.js | 49 ++ toolkit/devtools/performance/test/head.js | 88 ++- .../views/details-abstract-subview.js | 6 +- .../performance/views/details-js-call-tree.js | 38 +- .../views/details-memory-call-tree.js | 14 +- .../views/details-memory-flamegraph.js | 4 +- .../performance/views/details-waterfall.js | 10 + toolkit/devtools/performance/views/details.js | 25 +- .../performance/views/jit-optimizations.js | 46 +- .../devtools/performance/views/overview.js | 85 ++- .../devtools/performance/views/recordings.js | 4 - toolkit/devtools/performance/views/toolbar.js | 13 + .../responsivedesign/resize-commands.js | 45 +- .../scratchpad/scratchpad-commands.js | 6 +- toolkit/devtools/server/actors/gcli.js | 320 +++++--- toolkit/devtools/server/actors/profiler.js | 22 +- toolkit/devtools/server/actors/root.js | 2 +- .../devtools/server/tests/unit/head_dbg.js | 31 + .../tests/unit/test_profiler_activation-01.js | 16 +- .../tests/unit/test_profiler_bufferstatus.js | 127 +++ .../server/tests/unit/test_profiler_data.js | 10 +- .../tests/unit/test_profiler_getbufferinfo.js | 123 +++ .../devtools/server/tests/unit/xpcshell.ini | 1 + toolkit/devtools/shared/DeveloperToolbar.jsm | 243 +++--- toolkit/devtools/shared/devices.js | 635 ++------------- .../remote-resources.js => shared/getjson.js} | 25 +- toolkit/devtools/shared/moz.build | 2 + .../devtools/shared/profiler/frame-utils.js | 9 +- .../devtools/shared/profiler/tree-model.js | 15 +- toolkit/devtools/shared/source-utils.js | 128 ++++ toolkit/devtools/shared/test/browser.ini | 3 + .../devtools/shared/test/browser_devices.js | 50 ++ .../devtools/shared/test/browser_devices.json | 23 + .../test/browser_flame-graph-utils-01.js | 7 +- .../test/browser_flame-graph-utils-02.js | 18 +- .../test/browser_flame-graph-utils-03.js | 22 +- .../test/browser_flame-graph-utils-04.js | 38 +- .../test/browser_flame-graph-utils-05.js | 12 +- .../test/browser_flame-graph-utils-06.js | 18 +- ...er_telemetry_toolboxtabs_canvasdebugger.js | 117 +++ .../shared/test/browser_toolbar_tooltip.js | 12 +- toolkit/devtools/shared/test/head.js | 18 + .../shared/timeline/marker-details.js | 32 +- .../devtools/shared/widgets/FilterWidget.js | 720 ++++++++++++++++++ toolkit/devtools/shared/widgets/Tooltip.js | 111 ++- .../shared/widgets/filter-frame.xhtml | 29 + .../devtools/shared/widgets/filter-widget.css | 122 +++ .../styleeditor/styleeditor-commands.js | 38 +- .../test/browser_styleeditor_cmd_edit.js | 8 - .../devtools/styleinspector/computed-view.js | 4 +- toolkit/devtools/styleinspector/rule-view.js | 26 +- .../style-inspector-overlays.js | 25 +- .../styleinspector/style-inspector.js | 4 +- toolkit/devtools/tilt/tilt-commands.js | 70 +- .../devtools/webconsole/console-commands.js | 33 +- toolkit/devtools/webconsole/console-output.js | 2 + toolkit/devtools/webconsole/hudservice.js | 91 +-- toolkit/devtools/webconsole/webconsole.js | 2 +- .../webide/content/devicepreferences.js | 2 +- .../devtools/webide/content/devicesettings.js | 2 +- toolkit/devtools/webide/content/jar.mn | 5 + toolkit/devtools/webide/content/monitor.js | 2 +- toolkit/devtools/webide/content/newapp.js | 11 +- .../webide/content/permissionstable.js | 2 +- .../webide/content/project-listing.js | 49 ++ .../webide/content/project-listing.xhtml | 33 + .../devtools/webide/content/project-panel.js | 39 + .../devtools/webide/content/runtimedetails.js | 2 +- toolkit/devtools/webide/content/simulator.js | 320 ++++++++ .../devtools/webide/content/simulator.xhtml | 82 ++ toolkit/devtools/webide/content/webide.js | 311 +++----- toolkit/devtools/webide/content/webide.xul | 38 +- toolkit/devtools/webide/modules/addons.js | 8 +- .../devtools/webide/modules/app-manager.js | 121 ++- .../devtools/webide/modules/project-list.js | 327 ++++++++ toolkit/devtools/webide/modules/runtimes.js | 19 +- .../webide/modules/simulator-process.js | 56 +- toolkit/devtools/webide/modules/simulators.js | 216 +++++- toolkit/devtools/webide/modules/tab-store.js | 10 +- toolkit/devtools/webide/modules/utils.js | 34 +- toolkit/devtools/webide/moz.build | 12 +- toolkit/devtools/webide/test/browser_tabs.js | 17 +- toolkit/devtools/webide/test/chrome.ini | 4 + toolkit/devtools/webide/test/head.js | 20 +- .../devtools/webide/test/sidebars/browser.ini | 4 + .../devtools/webide/test/sidebars/chrome.ini | 8 + .../test/sidebars/test_duplicate_import.html | 75 ++ .../webide/test/sidebars/test_import.html | 79 ++ .../webide/test/sidebars/test_runtime.html | 145 ++++ .../webide/test/test_autoconnect_runtime.html | 6 +- .../webide/test/test_autoselect_project.html | 87 +++ toolkit/devtools/webide/test/test_basic.html | 4 + toolkit/devtools/webide/test/test_build.html | 6 +- .../webide/test/test_device_permissions.html | 2 - .../webide/test/test_device_preferences.html | 4 +- .../webide/test/test_device_runtime.html | 2 - .../webide/test/test_device_settings.html | 4 +- .../webide/test/test_duplicate_import.html | 8 +- .../webide/test/test_fullscreenToolbox.html | 5 +- toolkit/devtools/webide/test/test_import.html | 78 +- .../webide/test/test_manifestUpdate.html | 4 +- toolkit/devtools/webide/test/test_newapp.html | 2 +- .../devtools/webide/test/test_runtime.html | 67 +- .../devtools/webide/test/test_simulators.html | 341 +++++++++ .../devtools/webide/test/test_telemetry.html | 255 +++++++ toolkit/devtools/webide/themes/deck.css | 9 + toolkit/devtools/webide/themes/jar.mn | 2 + .../webide/themes/project-listing.css | 41 + toolkit/devtools/webide/themes/simulator.css | 41 + toolkit/devtools/webide/themes/webide.css | 46 +- toolkit/devtools/webide/webide-prefs.js | 1 + .../chrome/global/devtools/device.properties | 3 +- .../chrome/global/devtools/filterwidget.dtd | 14 + .../global/devtools/filterwidget.properties | 33 + .../chrome/global/devtools/gcli.properties | 2 +- .../global/devtools/gclicommands.properties | 23 + .../en-US/chrome/global/devtools/webide.dtd | 13 + .../chrome/global/devtools/webide.properties | 9 + toolkit/locales/jar.mn | 2 + toolkit/themes/shared/devtools/dark-theme.css | 5 +- .../themes/shared/devtools/light-theme.css | 5 +- .../shared/devtools/performance.inc.css | 64 +- toolkit/themes/shared/devtools/ruleview.css | 11 +- tools/profiler/GeckoProfiler.h | 4 +- tools/profiler/GeckoProfilerFunc.h | 3 +- tools/profiler/GeckoProfilerImpl.h | 2 +- tools/profiler/ProfileEntry.cpp | 70 +- tools/profiler/ProfileEntry.h | 26 +- tools/profiler/ProfileJSONWriter.h | 28 +- tools/profiler/TableTicker.cpp | 11 +- tools/profiler/TableTicker.h | 1 + tools/profiler/merge-profiles.py | 44 +- tools/profiler/nsProfiler.cpp | 7 +- tools/profiler/platform.cpp | 7 +- tools/profiler/tests/head_profiler.js | 23 + tools/profiler/tests/test_asm.js | 7 +- tools/profiler/tests/test_enterjit_osr.js | 9 +- 359 files changed, 11983 insertions(+), 6939 deletions(-) create mode 100644 browser/devtools/definitions.js create mode 100644 browser/devtools/webconsole/test/browser_console_addonsdk_loader_exception.js create mode 100644 browser/devtools/webconsole/test/browser_console_error_source_click.js create mode 100644 browser/themes/shared/devtools/images/add.svg create mode 100644 browser/themes/shared/devtools/images/filter-swatch.svg create mode 100644 browser/themes/shared/devtools/images/tool-profiler-active.svg create mode 100644 toolkit/devtools/framework/test/browser_toolbox_view_source_01.js create mode 100644 toolkit/devtools/framework/test/browser_toolbox_view_source_02.js create mode 100644 toolkit/devtools/framework/test/browser_toolbox_view_source_03.js create mode 100644 toolkit/devtools/framework/test/browser_toolbox_view_source_04.js create mode 100644 toolkit/devtools/framework/test/code_math.js create mode 100644 toolkit/devtools/framework/test/doc_viewsource.html delete mode 100644 toolkit/devtools/gcli/source/lib/gcli/api.js delete mode 100644 toolkit/devtools/gcli/source/lib/gcli/connectors/index.js delete mode 100644 toolkit/devtools/gcli/source/lib/gcli/connectors/protocol.js delete mode 100644 toolkit/devtools/gcli/source/lib/gcli/connectors/rdp.js delete mode 100644 toolkit/devtools/gcli/source/lib/gcli/connectors/remoted.js delete mode 100644 toolkit/devtools/gcli/source/lib/gcli/mozui/ffdisplay.js create mode 100644 toolkit/devtools/gcli/source/lib/gcli/system.js create mode 100644 toolkit/devtools/performance/modules/actors.js create mode 100644 toolkit/devtools/performance/test/browser_perf-compatibility-06.js create mode 100644 toolkit/devtools/performance/test/browser_perf-compatibility-07.js create mode 100644 toolkit/devtools/performance/test/browser_perf-highlighted.js create mode 100644 toolkit/devtools/performance/test/browser_perf-jit-view-02.js delete mode 100644 toolkit/devtools/performance/test/browser_perf-jump-to-debugger-01.js delete mode 100644 toolkit/devtools/performance/test/browser_perf-jump-to-debugger-02.js create mode 100644 toolkit/devtools/performance/test/browser_perf-recording-model-01.js create mode 100644 toolkit/devtools/performance/test/browser_perf-recording-model-02.js create mode 100644 toolkit/devtools/performance/test/browser_perf-recording-notices-03.js create mode 100644 toolkit/devtools/performance/test/browser_perf-recording-notices-04.js create mode 100644 toolkit/devtools/performance/test/browser_profiler-frame-utils-01.js create mode 100644 toolkit/devtools/performance/test/browser_retro-test.js create mode 100644 toolkit/devtools/server/tests/unit/test_profiler_bufferstatus.js create mode 100644 toolkit/devtools/server/tests/unit/test_profiler_getbufferinfo.js rename toolkit/devtools/{webide/modules/remote-resources.js => shared/getjson.js} (60%) create mode 100644 toolkit/devtools/shared/source-utils.js create mode 100644 toolkit/devtools/shared/test/browser_devices.js create mode 100644 toolkit/devtools/shared/test/browser_devices.json create mode 100644 toolkit/devtools/shared/test/browser_telemetry_toolboxtabs_canvasdebugger.js create mode 100644 toolkit/devtools/shared/widgets/FilterWidget.js create mode 100644 toolkit/devtools/shared/widgets/filter-frame.xhtml create mode 100644 toolkit/devtools/shared/widgets/filter-widget.css create mode 100644 toolkit/devtools/webide/content/project-listing.js create mode 100644 toolkit/devtools/webide/content/project-listing.xhtml create mode 100644 toolkit/devtools/webide/content/project-panel.js create mode 100644 toolkit/devtools/webide/content/simulator.js create mode 100644 toolkit/devtools/webide/content/simulator.xhtml create mode 100644 toolkit/devtools/webide/modules/project-list.js create mode 100644 toolkit/devtools/webide/test/sidebars/browser.ini create mode 100644 toolkit/devtools/webide/test/sidebars/chrome.ini create mode 100644 toolkit/devtools/webide/test/sidebars/test_duplicate_import.html create mode 100644 toolkit/devtools/webide/test/sidebars/test_import.html create mode 100644 toolkit/devtools/webide/test/sidebars/test_runtime.html create mode 100644 toolkit/devtools/webide/test/test_autoselect_project.html create mode 100644 toolkit/devtools/webide/test/test_simulators.html create mode 100644 toolkit/devtools/webide/test/test_telemetry.html create mode 100644 toolkit/devtools/webide/themes/project-listing.css create mode 100644 toolkit/devtools/webide/themes/simulator.css create mode 100644 toolkit/locales/en-US/chrome/global/devtools/filterwidget.dtd create mode 100644 toolkit/locales/en-US/chrome/global/devtools/filterwidget.properties diff --git a/browser/app/profile/palemoon.js b/browser/app/profile/palemoon.js index e33d6fa2d7..1328eedf2c 100644 --- a/browser/app/profile/palemoon.js +++ b/browser/app/profile/palemoon.js @@ -1094,6 +1094,20 @@ pref("devtools.performance.profiler.buffer-size", 10000000); pref("devtools.performance.profiler.sample-frequency-khz", 1); pref("devtools.performance.ui.show-jit-optimizations", false); +// If in aurora (40.0, will revert for 40.1), set default +// to retro mode. +// TODO bug 1160313 +#if MOZ_UPDATE_CHANNEL == aurora + pref("devtools.performance.ui.retro-mode", true); +#else + pref("devtools.performance.ui.retro-mode", false); +#endif + +// Set imgur upload client ID +pref("devtools.gcli.imgurClientID", '0df414e888d7240'); +// Imgur's upload URL +pref("devtools.gcli.imgurUploadURL", "https://api.imgur.com/3/image"); + // Whether the character encoding menu is under the main Firefox button. This // preference is a string so that localizers can alter it. pref("browser.menu.showCharacterEncoding", "chrome://browser/locale/browser.properties"); diff --git a/browser/devtools/definitions.js b/browser/devtools/definitions.js new file mode 100644 index 0000000000..c85443613d --- /dev/null +++ b/browser/devtools/definitions.js @@ -0,0 +1,410 @@ +/* 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 { Services } = require("resource://gre/modules/Services.jsm"); + +loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS); + +// Panels +loader.lazyGetter(this, "OptionsPanel", () => require("devtools/framework/toolbox-options").OptionsPanel); +loader.lazyGetter(this, "InspectorPanel", () => require("devtools/inspector/inspector-panel").InspectorPanel); +loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/webconsole/panel").WebConsolePanel); +loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/debugger/panel").DebuggerPanel); +loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/styleeditor/styleeditor-panel").StyleEditorPanel); +loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/shadereditor/panel").ShaderEditorPanel); +loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/canvasdebugger/panel").CanvasDebuggerPanel); +loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/webaudioeditor/panel").WebAudioEditorPanel); +loader.lazyGetter(this, "PerformancePanel", () => require("devtools/performance/panel").PerformancePanel); +loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/netmonitor/panel").NetMonitorPanel); +loader.lazyGetter(this, "StoragePanel", () => require("devtools/storage/panel").StoragePanel); +loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/scratchpad/scratchpad-panel").ScratchpadPanel); + +// Strings +const toolboxProps = "chrome://global/locale/devtools/toolbox.properties"; +const inspectorProps = "chrome://global/locale/devtools/inspector.properties"; +const webConsoleProps = "chrome://global/locale/devtools/webconsole.properties"; +const debuggerProps = "chrome://global/locale/devtools/debugger.properties"; +const styleEditorProps = "chrome://global/locale/devtools/styleeditor.properties"; +const shaderEditorProps = "chrome://global/locale/devtools/shadereditor.properties"; +const canvasDebuggerProps = "chrome://global/locale/devtools/canvasdebugger.properties"; +const webAudioEditorProps = "chrome://global/locale/devtools/webaudioeditor.properties"; +const profilerProps = "chrome://global/locale/devtools/profiler.properties"; +const netMonitorProps = "chrome://global/locale/devtools/netmonitor.properties"; +const storageProps = "chrome://global/locale/devtools/storage.properties"; +const scratchpadProps = "chrome://global/locale/devtools/scratchpad.properties"; + +loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps)); +loader.lazyGetter(this, "profilerStrings",() => Services.strings.createBundle(profilerProps)); +loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps)); +loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps)); +loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps)); +loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps)); +loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps)); +loader.lazyGetter(this, "webAudioEditorStrings", () => Services.strings.createBundle(webAudioEditorProps)); +loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps)); +loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps)); +loader.lazyGetter(this, "storageStrings", () => Services.strings.createBundle(storageProps)); +loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps)); + +let Tools = {}; +exports.Tools = Tools; + +// Definitions +Tools.options = { + id: "options", + ordinal: 0, + url: "chrome://global/content/devtools/framework/toolbox-options.xul", + icon: "chrome://global/skin/devtools/tool-options.svg", + invertIconForLightTheme: true, + bgTheme: "theme-body", + label: l10n("options.label", toolboxStrings), + iconOnly: true, + panelLabel: l10n("options.panelLabel", toolboxStrings), + tooltip: l10n("optionsButton.tooltip", toolboxStrings), + inMenu: false, + + isTargetSupported: function(target) { + return true; + }, + + build: function(iframeWindow, toolbox) { + return new OptionsPanel(iframeWindow, toolbox); + } +} + +Tools.inspector = { + id: "inspector", + accesskey: l10n("inspector.accesskey", inspectorStrings), + key: l10n("inspector.commandkey", inspectorStrings), + ordinal: 1, + modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift", + icon: "chrome://global/skin/devtools/tool-inspector.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/inspector/inspector.xul", + label: l10n("inspector.label", inspectorStrings), + panelLabel: l10n("inspector.panelLabel", inspectorStrings), + tooltip: l10n("inspector.tooltip", inspectorStrings), + inMenu: true, + commands: [ + "devtools/resize-commands", + "devtools/inspector/inspector-commands", + "devtools/eyedropper/commands.js" + ], + + preventClosingOnKey: true, + onkey: function(panel) { + panel.toolbox.highlighterUtils.togglePicker(); + }, + + isTargetSupported: function(target) { + return target.hasActor("inspector"); + }, + + build: function(iframeWindow, toolbox) { + return new InspectorPanel(iframeWindow, toolbox); + } +}; + +Tools.webConsole = { + id: "webconsole", + key: l10n("cmd.commandkey", webConsoleStrings), + accesskey: l10n("webConsoleCmd.accesskey", webConsoleStrings), + modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift", + ordinal: 2, + icon: "chrome://global/skin/devtools/tool-webconsole.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/webconsole.xul", + label: l10n("ToolboxTabWebconsole.label", webConsoleStrings), + menuLabel: l10n("MenuWebconsole.label", webConsoleStrings), + panelLabel: l10n("ToolboxWebConsole.panelLabel", webConsoleStrings), + tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings), + inMenu: true, + commands: "devtools/webconsole/console-commands", + + preventClosingOnKey: true, + onkey: function(panel, toolbox) { + if (toolbox.splitConsole) + return toolbox.focusConsoleInput(); + + panel.focusInput(); + }, + + isTargetSupported: function(target) { + return true; + }, + + build: function(iframeWindow, toolbox) { + return new WebConsolePanel(iframeWindow, toolbox); + } +}; + +Tools.jsdebugger = { + id: "jsdebugger", + key: l10n("debuggerMenu.commandkey", debuggerStrings), + accesskey: l10n("debuggerMenu.accesskey", debuggerStrings), + modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift", + ordinal: 3, + icon: "chrome://global/skin/devtools/tool-debugger.svg", + invertIconForLightTheme: true, + highlightedicon: "chrome://global/skin/devtools/tool-debugger-paused.svg", + url: "chrome://global/content/devtools/debugger.xul", + label: l10n("ToolboxDebugger.label", debuggerStrings), + panelLabel: l10n("ToolboxDebugger.panelLabel", debuggerStrings), + tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings), + inMenu: true, + commands: "devtools/debugger/debugger-commands", + + isTargetSupported: function(target) { + return true; + }, + + build: function(iframeWindow, toolbox) { + return new DebuggerPanel(iframeWindow, toolbox); + } +}; + +Tools.styleEditor = { + id: "styleeditor", + key: l10n("open.commandkey", styleEditorStrings), + ordinal: 4, + accesskey: l10n("open.accesskey", styleEditorStrings), + modifiers: "shift", + icon: "chrome://global/skin/devtools/tool-styleeditor.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/styleeditor.xul", + label: l10n("ToolboxStyleEditor.label", styleEditorStrings), + panelLabel: l10n("ToolboxStyleEditor.panelLabel", styleEditorStrings), + tooltip: l10n("ToolboxStyleEditor.tooltip2", styleEditorStrings), + inMenu: true, + commands: "devtools/styleeditor/styleeditor-commands", + + isTargetSupported: function(target) { + return target.hasActor("styleEditor") || target.hasActor("styleSheets"); + }, + + build: function(iframeWindow, toolbox) { + return new StyleEditorPanel(iframeWindow, toolbox); + } +}; + +Tools.shaderEditor = { + id: "shadereditor", + ordinal: 5, + visibilityswitch: "devtools.shadereditor.enabled", + icon: "chrome://global/skin/devtools/tool-styleeditor.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/shadereditor.xul", + label: l10n("ToolboxShaderEditor.label", shaderEditorStrings), + panelLabel: l10n("ToolboxShaderEditor.panelLabel", shaderEditorStrings), + tooltip: l10n("ToolboxShaderEditor.tooltip", shaderEditorStrings), + + isTargetSupported: function(target) { + return target.hasActor("webgl") && !target.chrome; + }, + + build: function(iframeWindow, toolbox) { + return new ShaderEditorPanel(iframeWindow, toolbox); + } +}; + +Tools.canvasDebugger = { + id: "canvasdebugger", + ordinal: 6, + visibilityswitch: "devtools.canvasdebugger.enabled", + icon: "chrome://global/skin/devtools/tool-styleeditor.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/canvasdebugger.xul", + label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings), + panelLabel: l10n("ToolboxCanvasDebugger.panelLabel", canvasDebuggerStrings), + tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings), + + // Hide the Canvas Debugger in the Add-on Debugger and Browser Toolbox + // (bug 1047520). + isTargetSupported: function(target) { + return target.hasActor("canvas") && !target.chrome; + }, + + build: function (iframeWindow, toolbox) { + return new CanvasDebuggerPanel(iframeWindow, toolbox); + } +}; + +Tools.performance = { + id: "performance", + ordinal: 7, + icon: "chrome://global/skin/devtools/tool-profiler.svg", + invertIconForLightTheme: true, + highlightedicon: "chrome://browser/skin/devtools/tool-profiler-active.svg", + url: "chrome://global/content/devtools/performance.xul", + visibilityswitch: "devtools.performance.enabled", + label: l10n("profiler.label2", profilerStrings), + panelLabel: l10n("profiler.panelLabel2", profilerStrings), + tooltip: l10n("profiler.tooltip2", profilerStrings), + accesskey: l10n("profiler.accesskey", profilerStrings), + key: l10n("profiler.commandkey2", profilerStrings), + modifiers: "shift", + inMenu: true, + + isTargetSupported: function (target) { + return target.hasActor("profiler"); + }, + + build: function (frame, target) { + return new PerformancePanel(frame, target); + } +}; + +Tools.netMonitor = { + id: "netmonitor", + accesskey: l10n("netmonitor.accesskey", netMonitorStrings), + key: l10n("netmonitor.commandkey", netMonitorStrings), + ordinal: 9, + modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift", + visibilityswitch: "devtools.netmonitor.enabled", + icon: "chrome://global/skin/devtools/tool-network.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/netmonitor.xul", + label: l10n("netmonitor.label", netMonitorStrings), + panelLabel: l10n("netmonitor.panelLabel", netMonitorStrings), + tooltip: l10n("netmonitor.tooltip", netMonitorStrings), + inMenu: true, + + isTargetSupported: function(target) { + return target.getTrait("networkMonitor"); + }, + + build: function(iframeWindow, toolbox) { + return new NetMonitorPanel(iframeWindow, toolbox); + } +}; + +Tools.storage = { + id: "storage", + key: l10n("storage.commandkey", storageStrings), + ordinal: 10, + accesskey: l10n("storage.accesskey", storageStrings), + modifiers: "shift", + visibilityswitch: "devtools.storage.enabled", + icon: "chrome://global/skin/devtools/tool-storage.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/storage.xul", + label: l10n("storage.label", storageStrings), + menuLabel: l10n("storage.menuLabel", storageStrings), + panelLabel: l10n("storage.panelLabel", storageStrings), + tooltip: l10n("storage.tooltip2", storageStrings), + inMenu: true, + + isTargetSupported: function(target) { + return target.isLocalTab || + ( target.hasActor("storage") && + target.getTrait("storageInspector") ); + }, + + build: function(iframeWindow, toolbox) { + return new StoragePanel(iframeWindow, toolbox); + } +}; + +Tools.webAudioEditor = { + id: "webaudioeditor", + ordinal: 11, + visibilityswitch: "devtools.webaudioeditor.enabled", + icon: "chrome://global/skin/devtools/tool-webaudio.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/webaudioeditor.xul", + label: l10n("ToolboxWebAudioEditor1.label", webAudioEditorStrings), + panelLabel: l10n("ToolboxWebAudioEditor1.panelLabel", webAudioEditorStrings), + tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings), + + isTargetSupported: function(target) { + return !target.chrome && target.hasActor("webaudio"); + }, + + build: function(iframeWindow, toolbox) { + return new WebAudioEditorPanel(iframeWindow, toolbox); + } +}; + +Tools.scratchpad = { + id: "scratchpad", + ordinal: 12, + visibilityswitch: "devtools.scratchpad.enabled", + icon: "chrome://global/skin/devtools/tool-scratchpad.svg", + invertIconForLightTheme: true, + url: "chrome://global/content/devtools/scratchpad.xul", + label: l10n("scratchpad.label", scratchpadStrings), + panelLabel: l10n("scratchpad.panelLabel", scratchpadStrings), + tooltip: l10n("scratchpad.tooltip", scratchpadStrings), + inMenu: false, + commands: "devtools/scratchpad/scratchpad-commands", + + isTargetSupported: function(target) { + return target.isRemote; + }, + + build: function(iframeWindow, toolbox) { + return new ScratchpadPanel(iframeWindow, toolbox); + } +}; + +let defaultTools = [ + Tools.options, + Tools.webConsole, + Tools.inspector, + Tools.jsdebugger, + Tools.styleEditor, + Tools.shaderEditor, + Tools.canvasDebugger, + Tools.webAudioEditor, + Tools.performance, + Tools.netMonitor, + Tools.storage, + Tools.scratchpad +]; + +exports.defaultTools = defaultTools; + +Tools.darkTheme = { + id: "dark", + label: l10n("options.darkTheme.label", toolboxStrings), + ordinal: 1, + stylesheets: ["chrome://global/skin/devtools/dark-theme.css"], + classList: ["theme-dark"], +}; + +Tools.lightTheme = { + id: "light", + label: l10n("options.lightTheme.label", toolboxStrings), + ordinal: 2, + stylesheets: ["chrome://global/skin/devtools/light-theme.css"], + classList: ["theme-light"], +}; + +exports.defaultThemes = [ + Tools.darkTheme, + Tools.lightTheme, +]; + +/** + * Lookup l10n string from a string bundle. + * + * @param {string} name + * The key to lookup. + * @param {StringBundle} bundle + * The key to lookup. + * @returns A localized version of the given key. + */ +function l10n(name, bundle) +{ + try { + return bundle.GetStringFromName(name); + } catch (ex) { + Services.console.logStringMessage("Error reading '" + name + "'"); + throw new Error("l10n error with " + name); + } +} diff --git a/browser/devtools/main.js b/browser/devtools/main.js index dfaed97c78..92e9934660 100644 --- a/browser/devtools/main.js +++ b/browser/devtools/main.js @@ -4,11 +4,20 @@ "use strict"; -const {Cc, Ci, Cu} = require("chrome"); - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +const { Cu } = require("chrome"); Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/devtools/gDevTools.jsm"); +const { gDevTools } = require("resource://gre/modules/devtools/gDevTools.jsm"); + +const { defaultTools, defaultThemes } = require("definitions"); + +defaultTools.forEach(definition => gDevTools.registerTool(definition)); +defaultThemes.forEach(definition => gDevTools.registerTheme(definition)); + +// Re-export for backwards compatibility, but we should probably the +// definitions from require("definitions") in the future +exports.defaultTools = require("definitions").defaultTools; +exports.defaultThemes = require("definitions").defaultThemes; +exports.Tools = require("definitions").Tools; Object.defineProperty(exports, "Toolbox", { get: () => require("devtools/framework/toolbox").Toolbox @@ -17,398 +26,7 @@ Object.defineProperty(exports, "TargetFactory", { get: () => require("devtools/framework/target").TargetFactory }); -loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS); - -let events = require("sdk/system/events"); - -// Panels -loader.lazyGetter(this, "OptionsPanel", () => require("devtools/framework/toolbox-options").OptionsPanel); -loader.lazyGetter(this, "InspectorPanel", () => require("devtools/inspector/inspector-panel").InspectorPanel); -loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/webconsole/panel").WebConsolePanel); -loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/debugger/panel").DebuggerPanel); -loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/styleeditor/styleeditor-panel").StyleEditorPanel); -loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/shadereditor/panel").ShaderEditorPanel); -loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/canvasdebugger/panel").CanvasDebuggerPanel); -loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/webaudioeditor/panel").WebAudioEditorPanel); -loader.lazyGetter(this, "PerformancePanel", () => require("devtools/performance/panel").PerformancePanel); -loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/netmonitor/panel").NetMonitorPanel); -loader.lazyGetter(this, "StoragePanel", () => require("devtools/storage/panel").StoragePanel); -loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/scratchpad/scratchpad-panel").ScratchpadPanel); - -// Strings -const toolboxProps = "chrome://global/locale/devtools/toolbox.properties"; -const inspectorProps = "chrome://global/locale/devtools/inspector.properties"; -const webConsoleProps = "chrome://global/locale/devtools/webconsole.properties"; -const debuggerProps = "chrome://global/locale/devtools/debugger.properties"; -const styleEditorProps = "chrome://global/locale/devtools/styleeditor.properties"; -const shaderEditorProps = "chrome://global/locale/devtools/shadereditor.properties"; -const canvasDebuggerProps = "chrome://global/locale/devtools/canvasdebugger.properties"; -const webAudioEditorProps = "chrome://global/locale/devtools/webaudioeditor.properties"; -const profilerProps = "chrome://global/locale/devtools/profiler.properties"; -const netMonitorProps = "chrome://global/locale/devtools/netmonitor.properties"; -const storageProps = "chrome://global/locale/devtools/storage.properties"; -const scratchpadProps = "chrome://global/locale/devtools/scratchpad.properties"; - -loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps)); -loader.lazyGetter(this, "profilerStrings",() => Services.strings.createBundle(profilerProps)); -loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps)); -loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps)); -loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps)); -loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps)); -loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps)); -loader.lazyGetter(this, "webAudioEditorStrings", () => Services.strings.createBundle(webAudioEditorProps)); -loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps)); -loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps)); -loader.lazyGetter(this, "storageStrings", () => Services.strings.createBundle(storageProps)); -loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps)); - -let Tools = {}; -exports.Tools = Tools; - -// Definitions -Tools.options = { - id: "options", - ordinal: 0, - url: "chrome://global/content/devtools/framework/toolbox-options.xul", - icon: "chrome://global/skin/devtools/tool-options.svg", - invertIconForLightTheme: true, - bgTheme: "theme-body", - label: l10n("options.label", toolboxStrings), - iconOnly: true, - panelLabel: l10n("options.panelLabel", toolboxStrings), - tooltip: l10n("optionsButton.tooltip", toolboxStrings), - inMenu: false, - - isTargetSupported: function(target) { - return true; - }, - - build: function(iframeWindow, toolbox) { - return new OptionsPanel(iframeWindow, toolbox); - } -} - -Tools.inspector = { - id: "inspector", - accesskey: l10n("inspector.accesskey", inspectorStrings), - key: l10n("inspector.commandkey", inspectorStrings), - ordinal: 1, - modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift", - icon: "chrome://global/skin/devtools/tool-inspector.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/inspector/inspector.xul", - label: l10n("inspector.label", inspectorStrings), - panelLabel: l10n("inspector.panelLabel", inspectorStrings), - tooltip: l10n("inspector.tooltip", inspectorStrings), - inMenu: true, - commands: [ - "devtools/resize-commands", - "devtools/inspector/inspector-commands", - "devtools/eyedropper/commands.js" - ], - - preventClosingOnKey: true, - onkey: function(panel) { - panel.toolbox.highlighterUtils.togglePicker(); - }, - - isTargetSupported: function(target) { - return target.hasActor("inspector"); - }, - - build: function(iframeWindow, toolbox) { - return new InspectorPanel(iframeWindow, toolbox); - } -}; - -Tools.webConsole = { - id: "webconsole", - key: l10n("cmd.commandkey", webConsoleStrings), - accesskey: l10n("webConsoleCmd.accesskey", webConsoleStrings), - modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift", - ordinal: 2, - icon: "chrome://global/skin/devtools/tool-webconsole.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/webconsole.xul", - label: l10n("ToolboxTabWebconsole.label", webConsoleStrings), - menuLabel: l10n("MenuWebconsole.label", webConsoleStrings), - panelLabel: l10n("ToolboxWebConsole.panelLabel", webConsoleStrings), - tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings), - inMenu: true, - commands: "devtools/webconsole/console-commands", - - preventClosingOnKey: true, - onkey: function(panel, toolbox) { - if (toolbox.splitConsole) - return toolbox.focusConsoleInput(); - - panel.focusInput(); - }, - - isTargetSupported: function(target) { - return true; - }, - - build: function(iframeWindow, toolbox) { - return new WebConsolePanel(iframeWindow, toolbox); - } -}; - -Tools.jsdebugger = { - id: "jsdebugger", - key: l10n("debuggerMenu.commandkey", debuggerStrings), - accesskey: l10n("debuggerMenu.accesskey", debuggerStrings), - modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift", - ordinal: 3, - icon: "chrome://global/skin/devtools/tool-debugger.svg", - invertIconForLightTheme: true, - highlightedicon: "chrome://global/skin/devtools/tool-debugger-paused.svg", - url: "chrome://global/content/devtools/debugger.xul", - label: l10n("ToolboxDebugger.label", debuggerStrings), - panelLabel: l10n("ToolboxDebugger.panelLabel", debuggerStrings), - tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings), - inMenu: true, - commands: "devtools/debugger/debugger-commands", - - isTargetSupported: function(target) { - return true; - }, - - build: function(iframeWindow, toolbox) { - return new DebuggerPanel(iframeWindow, toolbox); - } -}; - -Tools.styleEditor = { - id: "styleeditor", - key: l10n("open.commandkey", styleEditorStrings), - ordinal: 4, - accesskey: l10n("open.accesskey", styleEditorStrings), - modifiers: "shift", - icon: "chrome://global/skin/devtools/tool-styleeditor.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/styleeditor.xul", - label: l10n("ToolboxStyleEditor.label", styleEditorStrings), - panelLabel: l10n("ToolboxStyleEditor.panelLabel", styleEditorStrings), - tooltip: l10n("ToolboxStyleEditor.tooltip2", styleEditorStrings), - inMenu: true, - commands: "devtools/styleeditor/styleeditor-commands", - - isTargetSupported: function(target) { - return target.hasActor("styleEditor") || target.hasActor("styleSheets"); - }, - - build: function(iframeWindow, toolbox) { - return new StyleEditorPanel(iframeWindow, toolbox); - } -}; - -Tools.shaderEditor = { - id: "shadereditor", - ordinal: 5, - visibilityswitch: "devtools.shadereditor.enabled", - icon: "chrome://global/skin/devtools/tool-styleeditor.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/shadereditor.xul", - label: l10n("ToolboxShaderEditor.label", shaderEditorStrings), - panelLabel: l10n("ToolboxShaderEditor.panelLabel", shaderEditorStrings), - tooltip: l10n("ToolboxShaderEditor.tooltip", shaderEditorStrings), - - isTargetSupported: function(target) { - return target.hasActor("webgl") && !target.chrome; - }, - - build: function(iframeWindow, toolbox) { - return new ShaderEditorPanel(iframeWindow, toolbox); - } -}; - -Tools.canvasDebugger = { - id: "canvasdebugger", - ordinal: 6, - visibilityswitch: "devtools.canvasdebugger.enabled", - icon: "chrome://global/skin/devtools/tool-styleeditor.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/canvasdebugger.xul", - label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings), - panelLabel: l10n("ToolboxCanvasDebugger.panelLabel", canvasDebuggerStrings), - tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings), - - // Hide the Canvas Debugger in the Add-on Debugger and Browser Toolbox - // (bug 1047520). - isTargetSupported: function(target) { - return target.hasActor("canvas") && !target.chrome; - }, - - build: function (iframeWindow, toolbox) { - return new CanvasDebuggerPanel(iframeWindow, toolbox); - } -}; - -Tools.performance = { - id: "performance", - ordinal: 7, - icon: "chrome://global/skin/devtools/tool-profiler.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/performance.xul", - visibilityswitch: "devtools.performance.enabled", - label: l10n("profiler.label2", profilerStrings), - panelLabel: l10n("profiler.panelLabel2", profilerStrings), - tooltip: l10n("profiler.tooltip2", profilerStrings), - accesskey: l10n("profiler.accesskey", profilerStrings), - key: l10n("profiler.commandkey2", profilerStrings), - modifiers: "shift", - inMenu: true, - - isTargetSupported: function (target) { - return target.hasActor("profiler"); - }, - - build: function (frame, target) { - return new PerformancePanel(frame, target); - } -}; - -Tools.netMonitor = { - id: "netmonitor", - accesskey: l10n("netmonitor.accesskey", netMonitorStrings), - key: l10n("netmonitor.commandkey", netMonitorStrings), - ordinal: 9, - modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift", - visibilityswitch: "devtools.netmonitor.enabled", - icon: "chrome://global/skin/devtools/tool-network.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/netmonitor.xul", - label: l10n("netmonitor.label", netMonitorStrings), - panelLabel: l10n("netmonitor.panelLabel", netMonitorStrings), - tooltip: l10n("netmonitor.tooltip", netMonitorStrings), - inMenu: true, - - isTargetSupported: function(target) { - return target.getTrait("networkMonitor"); - }, - - build: function(iframeWindow, toolbox) { - return new NetMonitorPanel(iframeWindow, toolbox); - } -}; - -Tools.storage = { - id: "storage", - key: l10n("storage.commandkey", storageStrings), - ordinal: 10, - accesskey: l10n("storage.accesskey", storageStrings), - modifiers: "shift", - visibilityswitch: "devtools.storage.enabled", - icon: "chrome://global/skin/devtools/tool-storage.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/storage.xul", - label: l10n("storage.label", storageStrings), - menuLabel: l10n("storage.menuLabel", storageStrings), - panelLabel: l10n("storage.panelLabel", storageStrings), - tooltip: l10n("storage.tooltip2", storageStrings), - inMenu: true, - - isTargetSupported: function(target) { - return target.isLocalTab || - ( target.hasActor("storage") && - target.getTrait("storageInspector") ); - }, - - build: function(iframeWindow, toolbox) { - return new StoragePanel(iframeWindow, toolbox); - } -}; - -Tools.webAudioEditor = { - id: "webaudioeditor", - ordinal: 11, - visibilityswitch: "devtools.webaudioeditor.enabled", - icon: "chrome://global/skin/devtools/tool-webaudio.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/webaudioeditor.xul", - label: l10n("ToolboxWebAudioEditor1.label", webAudioEditorStrings), - panelLabel: l10n("ToolboxWebAudioEditor1.panelLabel", webAudioEditorStrings), - tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings), - - isTargetSupported: function(target) { - return !target.chrome && target.hasActor("webaudio"); - }, - - build: function(iframeWindow, toolbox) { - return new WebAudioEditorPanel(iframeWindow, toolbox); - } -}; - -Tools.scratchpad = { - id: "scratchpad", - ordinal: 12, - visibilityswitch: "devtools.scratchpad.enabled", - icon: "chrome://global/skin/devtools/tool-scratchpad.svg", - invertIconForLightTheme: true, - url: "chrome://global/content/devtools/scratchpad.xul", - label: l10n("scratchpad.label", scratchpadStrings), - panelLabel: l10n("scratchpad.panelLabel", scratchpadStrings), - tooltip: l10n("scratchpad.tooltip", scratchpadStrings), - inMenu: false, - commands: "devtools/scratchpad/scratchpad-commands", - - isTargetSupported: function(target) { - return target.isRemote; - }, - - build: function(iframeWindow, toolbox) { - return new ScratchpadPanel(iframeWindow, toolbox); - } -}; - -let defaultTools = [ - Tools.options, - Tools.webConsole, - Tools.inspector, - Tools.jsdebugger, - Tools.styleEditor, - Tools.shaderEditor, - Tools.canvasDebugger, - Tools.webAudioEditor, - Tools.performance, - Tools.netMonitor, - Tools.storage, - Tools.scratchpad -]; - -exports.defaultTools = defaultTools; - -for (let definition of defaultTools) { - gDevTools.registerTool(definition); -} - -Tools.darkTheme = { - id: "dark", - label: l10n("options.darkTheme.label", toolboxStrings), - ordinal: 1, - stylesheets: ["chrome://global/skin/devtools/dark-theme.css"], - classList: ["theme-dark"], -}; - -Tools.lightTheme = { - id: "light", - label: l10n("options.lightTheme.label", toolboxStrings), - ordinal: 2, - stylesheets: ["chrome://global/skin/devtools/light-theme.css"], - classList: ["theme-light"], -}; - -let defaultThemes = [ - Tools.darkTheme, - Tools.lightTheme, -]; - -for (let definition of defaultThemes) { - gDevTools.registerTheme(definition); -} - -var unloadObserver = { +const unloadObserver = { observe: function(subject, topic, data) { if (subject.wrappedJSObject === require("@loader/unload")) { Services.obs.removeObserver(unloadObserver, "sdk:loader:destroy"); @@ -423,23 +41,5 @@ var unloadObserver = { }; Services.obs.addObserver(unloadObserver, "sdk:loader:destroy", false); +const events = require("sdk/system/events"); events.emit("devtools-loaded", {}); - -/** - * Lookup l10n string from a string bundle. - * - * @param {string} name - * The key to lookup. - * @param {StringBundle} bundle - * The key to lookup. - * @returns A localized version of the given key. - */ -function l10n(name, bundle) -{ - try { - return bundle.GetStringFromName(name); - } catch (ex) { - Services.console.logStringMessage("Error reading '" + name + "'"); - throw new Error("l10n error with " + name); - } -} diff --git a/browser/devtools/moz.build b/browser/devtools/moz.build index 8e3be12259..d640fc60ad 100644 --- a/browser/devtools/moz.build +++ b/browser/devtools/moz.build @@ -12,5 +12,6 @@ EXTRA_COMPONENTS += [ JAR_MANIFESTS += ['jar.mn'] EXTRA_JS_MODULES.devtools += [ + 'definitions.js', 'main.js', ] diff --git a/browser/devtools/webconsole/test/browser_console_addonsdk_loader_exception.js b/browser/devtools/webconsole/test/browser_console_addonsdk_loader_exception.js new file mode 100644 index 0000000000..8ed54f356d --- /dev/null +++ b/browser/devtools/webconsole/test/browser_console_addonsdk_loader_exception.js @@ -0,0 +1,90 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Check that exceptions from scripts loaded with the addon-sdk loader are +// opened correctly in View Source from the Browser Console. +// See bug 866950. + +"use strict"; + +const TEST_URI = "data:text/html;charset=utf8,

hello world from bug 866950"; + +function test() +{ + requestLongerTimeout(2); + + let webconsole, browserconsole; + + Task.spawn(runner).then(finishTest); + + function* runner() { + let {tab} = yield loadTab(TEST_URI); + webconsole = yield openConsole(tab); + ok(webconsole, "web console opened"); + + browserconsole = yield HUDService.toggleBrowserConsole(); + ok(browserconsole, "browser console opened"); + + // Cause an exception in a script loaded with the addon-sdk loader. + let toolbox = gDevTools.getToolbox(webconsole.target); + let oldPanels = toolbox._toolPanels; + toolbox._toolPanels = {}; // non-iterable + + function fixToolbox() { + toolbox._toolPanels = oldPanels; + } + + info("generate exception and wait for message"); + + executeSoon(() => { + executeSoon(fixToolbox); + expectUncaughtException(); + toolbox.getToolPanels(); + }); + + let [result] = yield waitForMessages({ + webconsole: browserconsole, + messages: [{ + text: "TypeError: this._toolPanels is not iterable", + category: CATEGORY_JS, + severity: SEVERITY_ERROR, + }], + }); + + fixToolbox(); + + let msg = [...result.matched][0]; + ok(msg, "message element found"); + let locationNode = msg.querySelector(".message-location"); + ok(locationNode, "message location element found"); + + let title = locationNode.getAttribute("title"); + info("location node title: " + title); + isnot(title.indexOf(" -> "), -1, "error comes from a subscript"); + + let viewSource = browserconsole.viewSource; + let URL = null; + let clickPromise = promise.defer(); + browserconsole.viewSourceInDebugger = (aURL) => { + info("browserconsole.viewSourceInDebugger() was invoked: " + aURL); + URL = aURL; + clickPromise.resolve(null); + }; + + msg.scrollIntoView(); + EventUtils.synthesizeMouse(locationNode, 2, 2, {}, + browserconsole.iframeWindow); + + info("wait for click on locationNode"); + yield clickPromise; + + info("view-source url: " + URL); + ok(URL, "we have some source URL after the click"); + isnot(URL.indexOf("toolbox.js"), -1, "we have the expected view source URL"); + is(URL.indexOf("->"), -1, "no -> in the URL given to view-source"); + + browserconsole.viewSourceInDebugger = viewSource; + } +} diff --git a/browser/devtools/webconsole/test/browser_console_error_source_click.js b/browser/devtools/webconsole/test/browser_console_error_source_click.js new file mode 100644 index 0000000000..3443ca3fdc --- /dev/null +++ b/browser/devtools/webconsole/test/browser_console_error_source_click.js @@ -0,0 +1,73 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Check that JS errors and CSS warnings open view source when their source link +// is clicked in the Browser Console. See bug 877778. + +const TEST_URI = "data:text/html;charset=utf8,

hello world from bug 877778 " + + ""; +function test() +{ + let hud; + + loadTab(TEST_URI).then(() => { + HUDService.toggleBrowserConsole().then(browserConsoleOpened); + }); + + function browserConsoleOpened(aHud) + { + hud = aHud; + ok(hud, "browser console opened"); + + let button = content.document.querySelector("button"); + ok(button, "button element found"); + + info("generate exception and wait for the message"); + executeSoon(() => { + expectUncaughtException(); + button.click(); + }); + + waitForMessages({ + webconsole: hud, + messages: [ + { + text: "ReferenceError: foobar is not defined", + category: CATEGORY_JS, + severity: SEVERITY_ERROR, + }, + { + text: "Unknown property 'test-color'", + category: CATEGORY_CSS, + severity: SEVERITY_WARNING, + }, + ], + }).then(onMessageFound); + } + + function onMessageFound(results) + { + let viewSource = hud.viewSource; + let viewSourceCalled = false; + hud.viewSourceInDebugger = () => viewSourceCalled = true; + + for (let result of results) { + viewSourceCalled = false; + + let msg = [...results[0].matched][0]; + ok(msg, "message element found for: " + result.text); + let locationNode = msg.querySelector(".message-location"); + ok(locationNode, "message location element found"); + + EventUtils.synthesizeMouse(locationNode, 2, 2, {}, hud.iframeWindow); + + ok(viewSourceCalled, "view source opened"); + } + + hud.viewSourceInDebugger = viewSource; + finishTest(); + } +} diff --git a/browser/themes/linux/jar.mn b/browser/themes/linux/jar.mn index aa9bca6b88..f998f6fc40 100644 --- a/browser/themes/linux/jar.mn +++ b/browser/themes/linux/jar.mn @@ -125,9 +125,12 @@ browser.jar: skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png) skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png) skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png) + skin/classic/browser/devtools/add.svg (../shared/devtools/images/add.svg) + skin/classic/browser/devtools/filter-swatch.svg (../shared/devtools/images/filter-swatch.svg) skin/classic/browser/devtools/search-clear-failed.svg (../shared/devtools/images/search-clear-failed.svg) skin/classic/browser/devtools/search-clear-light.svg (../shared/devtools/images/search-clear-light.svg) skin/classic/browser/devtools/search-clear-dark.svg (../shared/devtools/images/search-clear-dark.svg) + skin/classic/browser/devtools/tool-profiler-active.svg (../shared/devtools/images/tool-profiler-active.svg) #ifdef MOZ_SERVICES_SYNC skin/classic/browser/sync-16-throbber.png skin/classic/browser/sync-16.png diff --git a/browser/themes/osx/jar.mn b/browser/themes/osx/jar.mn index 1b8a8c6f82..d5e55d436a 100644 --- a/browser/themes/osx/jar.mn +++ b/browser/themes/osx/jar.mn @@ -160,9 +160,12 @@ browser.jar: skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png) skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png) skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png) + skin/classic/browser/devtools/add.svg (../shared/devtools/images/add.svg) + skin/classic/browser/devtools/filter-swatch.svg (../shared/devtools/images/filter-swatch.svg) skin/classic/browser/devtools/search-clear-failed.svg (../shared/devtools/images/search-clear-failed.svg) skin/classic/browser/devtools/search-clear-light.svg (../shared/devtools/images/search-clear-light.svg) skin/classic/browser/devtools/search-clear-dark.svg (../shared/devtools/images/search-clear-dark.svg) + skin/classic/browser/devtools/tool-profiler-active.svg (../shared/devtools/images/tool-profiler-active.svg) #ifdef MOZ_SERVICES_SYNC skin/classic/browser/sync-throbber.png skin/classic/browser/sync-16.png diff --git a/browser/themes/shared/devtools/images/add.svg b/browser/themes/shared/devtools/images/add.svg new file mode 100644 index 0000000000..af162e3604 --- /dev/null +++ b/browser/themes/shared/devtools/images/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/browser/themes/shared/devtools/images/filter-swatch.svg b/browser/themes/shared/devtools/images/filter-swatch.svg new file mode 100644 index 0000000000..37dcab46b2 --- /dev/null +++ b/browser/themes/shared/devtools/images/filter-swatch.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/browser/themes/shared/devtools/images/tool-profiler-active.svg b/browser/themes/shared/devtools/images/tool-profiler-active.svg new file mode 100644 index 0000000000..eff16737db --- /dev/null +++ b/browser/themes/shared/devtools/images/tool-profiler-active.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/browser/themes/windows/jar.mn b/browser/themes/windows/jar.mn index fb47c2e4bd..dd030d9338 100644 --- a/browser/themes/windows/jar.mn +++ b/browser/themes/windows/jar.mn @@ -156,9 +156,12 @@ browser.jar: skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png) skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png) skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png) + skin/classic/browser/devtools/add.svg (../shared/devtools/images/add.svg) + skin/classic/browser/devtools/filter-swatch.svg (../shared/devtools/images/filter-swatch.svg) skin/classic/browser/devtools/search-clear-failed.svg (../shared/devtools/images/search-clear-failed.svg) skin/classic/browser/devtools/search-clear-light.svg (../shared/devtools/images/search-clear-light.svg) skin/classic/browser/devtools/search-clear-dark.svg (../shared/devtools/images/search-clear-dark.svg) + skin/classic/browser/devtools/tool-profiler-active.svg (../shared/devtools/images/tool-profiler-active.svg) #ifdef MOZ_SERVICES_SYNC skin/classic/browser/sync-throbber.png skin/classic/browser/sync-16.png diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 14457c2f74..5b94e70baa 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2647,10 +2647,9 @@ ContentChild::RecvStopProfiler() bool ContentChild::RecvGetProfile(nsCString* aProfile) { - char* profile = profiler_get_profile(); + UniquePtr profile = profiler_get_profile(); if (profile) { - *aProfile = nsCString(profile, strlen(profile)); - free(profile); + *aProfile = nsCString(profile.get(), strlen(profile.get())); } else { *aProfile = EmptyCString(); } diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index cd1dc575d6..c782cacf44 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -2510,10 +2510,9 @@ PluginModuleChild::RecvStopProfiler() bool PluginModuleChild::AnswerGetProfile(nsCString* aProfile) { - char* profile = profiler_get_profile(); + UniquePtr profile = profiler_get_profile(); if (profile != nullptr) { - *aProfile = nsCString(profile, strlen(profile)); - free(profile); + *aProfile = nsCString(profile.get(), strlen(profile.get())); } else { *aProfile = nsCString("", 0); } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 8837264685..c887425965 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1154,6 +1154,12 @@ pref("devtools.telemetry.tools.opened.version", "{}"); pref("devtools.selfxss.count", 0); #endif //MOZ_DEVTOOLS +// URL of the remote JSON catalog used for device simulation +pref("devtools.devices.url", "https://code.cdn.mozilla.net/devices/devices.json"); + +// URL of the remote JSON catalog used for device simulation +pref("devtools.devices.url", "https://code.cdn.mozilla.net/devices/devices.json"); + // view source pref("view_source.syntax_highlight", true); pref("view_source.wrap_long_lines", false); diff --git a/toolkit/commonjs/sdk/panel/utils.js b/toolkit/commonjs/sdk/panel/utils.js index 6cd7652624..577ed1e6c5 100644 --- a/toolkit/commonjs/sdk/panel/utils.js +++ b/toolkit/commonjs/sdk/panel/utils.js @@ -95,6 +95,7 @@ function close(panel) { // when quitting the host application while a panel is visible. To suppress // these errors, check for "hidePopup" in panel before calling it. // It's not clear if there's an issue or it's expected behavior. + // See Bug 1151796. return panel.hidePopup && panel.hidePopup(); } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 706a5ff878..78e5f5fc52 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -5452,16 +5452,50 @@ "n_values": 13, "description": "Screen resolution of DevTools user (0:lower, 1:800x600, 2:1024x768, 3:1280x800, 4:1280x1024, 5:1366x768, 6:1440x900, 7:1920x1080, 8:2560×1440, 9:2560×1600, 10:2880x1800, 11:other, 12:higher)" }, + "DEVTOOLS_WEBIDE_OPENED_BOOLEAN": { + "expires_in_version": "never", + "kind": "boolean", + "description": "How many times has the DevTools WebIDE been opened?" + }, + "DEVTOOLS_CANVASDEBUGGER_OPENED_BOOLEAN": { + "expires_in_version": "never", + "kind": "boolean", + "description": "How many times has the devtool's Canvas Debugger been opened?" + }, "DEVTOOLS_TOOLBOX_OPENED_BOOLEAN": { "expires_in_version": "never", "kind": "boolean", "description": "How many times has the devtool's toolbox been opened?" }, + "DEVTOOLS_WEBIDE_OPENED_PER_USER_FLAG": { + "expires_in_version": "never", + "kind": "flag", + "description": "How many users have opened the DevTools WebIDE?" + }, + "DEVTOOLS_CANVASDEBUGGER_OPENED_PER_USER_FLAG": { + "expires_in_version": "never", + "kind": "flag", + "description": "How many users have opened the devtool's Canvas Debugger?" + }, "DEVTOOLS_TOOLBOX_OPENED_PER_USER_FLAG": { "expires_in_version": "never", "kind": "flag", "description": "How many times has the devtool's toolbox been opened?" }, + "DEVTOOLS_WEBIDE_TIME_ACTIVE_SECONDS": { + "expires_in_version": "never", + "kind": "exponential", + "high": "10000000", + "n_buckets": 100, + "description": "How long has WebIDE been active (seconds)" + }, + "DEVTOOLS_CANVASDEBUGGER_TIME_ACTIVE_SECONDS": { + "expires_in_version": "never", + "kind": "exponential", + "high": "10000000", + "n_buckets": 100, + "description": "How long has the Canvas Debugger been active (seconds)" + }, "DEVTOOLS_TOOLBOX_TIME_ACTIVE_SECONDS": { "expires_in_version": "never", "kind": "exponential", @@ -5475,7 +5509,54 @@ "high": "10000000", "n_buckets": 100, "description": "How long has the options panel been active (seconds)" -}, + }, + "DEVTOOLS_WEBIDE_CONNECTION_RESULT": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Did WebIDE runtime connection succeed?" + }, + "DEVTOOLS_WEBIDE_USB_CONNECTION_RESULT": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Did WebIDE USB runtime connection succeed?" + }, + "DEVTOOLS_WEBIDE_WIFI_CONNECTION_RESULT": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Did WebIDE WiFi runtime connection succeed?" + }, + "DEVTOOLS_WEBIDE_SIMULATOR_CONNECTION_RESULT": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Did WebIDE simulator runtime connection succeed?" + }, + "DEVTOOLS_WEBIDE_REMOTE_CONNECTION_RESULT": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Did WebIDE remote runtime connection succeed?" + }, + "DEVTOOLS_WEBIDE_LOCAL_CONNECTION_RESULT": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Did WebIDE local runtime connection succeed?" + }, + "DEVTOOLS_WEBIDE_CONNECTION_TIME_SECONDS": { + "expires_in_version": "never", + "kind": "exponential", + "high": "10000000", + "n_buckets": 100, + "description": "How long was WebIDE connected to a runtime (seconds)?" + }, + "DEVTOOLS_WEBIDE_CONNECTION_PLAY_USED": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Was WebIDE's play button used during this runtime connection?" + }, + "DEVTOOLS_WEBIDE_CONNECTION_DEBUG_USED": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Was WebIDE's debug button used during this runtime connection?" + }, "DEVTOOLS_TABS_OPEN_PEAK_LINEAR": { "expires_in_version": "never", "kind": "linear", diff --git a/toolkit/devtools/Loader.jsm b/toolkit/devtools/Loader.jsm index eed7f774ac..f8289e5473 100644 --- a/toolkit/devtools/Loader.jsm +++ b/toolkit/devtools/Loader.jsm @@ -79,6 +79,7 @@ BuiltinProvider.prototype = { // corresponding addition to the SrcdirProvider mapping below as well. "": "resource://gre/modules/commonjs/", "main": "resource:///modules/devtools/main.js", + "definitions": "resource:///modules/devtools/definitions.js", "devtools": "resource://gre/modules/devtools", "devtools/toolkit": "resource://gre/modules/devtools", "devtools/server": "resource://gre/modules/devtools/server", @@ -135,6 +136,7 @@ SrcdirProvider.prototype = { let devtoolsDir = OS.Path.join(srcdir, "browser", "devtools"); let toolkitDir = OS.Path.join(srcdir, "toolkit", "devtools"); let mainURI = this.fileURI(OS.Path.join(devtoolsDir, "main.js")); + let definitionsURI = this.fileURI(OS.Path.join(devtoolsDir, "definitions.js")); let devtoolsURI = this.fileURI(devtoolsDir); let toolkitURI = this.fileURI(toolkitDir); let serverURI = this.fileURI(OS.Path.join(toolkitDir, "server")); @@ -161,6 +163,7 @@ SrcdirProvider.prototype = { paths: { "": "resource://gre/modules/commonjs/", "main": mainURI, + "definitions": definitionsURI, "devtools": devtoolsURI, "devtools/toolkit": toolkitURI, "devtools/server": serverURI, diff --git a/toolkit/devtools/canvasdebugger/callslist.js b/toolkit/devtools/canvasdebugger/callslist.js index bce1c9eddf..da0317c47b 100644 --- a/toolkit/devtools/canvasdebugger/callslist.js +++ b/toolkit/devtools/canvasdebugger/callslist.js @@ -384,7 +384,7 @@ let CallsListView = Heritage.extend(WidgetMethods, { // If clicking on the location, jump to the Debugger. if (e.target.classList.contains("call-item-location")) { let { file, line } = callItem.attachment.actor; - viewSourceInDebugger(file, line); + this._viewSourceInDebugger(file, line); return; } // Otherwise hide the call stack. @@ -414,7 +414,7 @@ let CallsListView = Heritage.extend(WidgetMethods, { let name = document.createElement("label"); name.className = "plain call-item-stack-fn-name"; - name.setAttribute("value", "??" + call.name + "()"); + name.setAttribute("value", "↳ " + call.name + "()"); contents.appendChild(name); let spacer = document.createElement("spacer"); @@ -456,7 +456,7 @@ let CallsListView = Heritage.extend(WidgetMethods, { * The line of the respective function. */ _onStackFileClick: function(e, { file, line }) { - viewSourceInDebugger(file, line); + this._viewSourceInDebugger(file, line); }, /** @@ -501,7 +501,7 @@ let CallsListView = Heritage.extend(WidgetMethods, { } let callItem = this.selectedItem; let { file, line } = callItem.attachment.actor; - viewSourceInDebugger(file, line); + this._viewSourceInDebugger(file, line); }, /** @@ -509,5 +509,18 @@ let CallsListView = Heritage.extend(WidgetMethods, { */ _onStepOut: function() { this.selectedIndex = this.itemCount - 1; + }, + + /** + * Opens the specified file and line in the debugger. Falls back to Firefox's View Source. + */ + _viewSourceInDebugger: function (file, line) { + gToolbox.viewSourceInDebugger(file, line).then(success => { + if (success) { + window.emit(EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER); + } else { + window.emit(EVENTS.SOURCE_NOT_FOUND_IN_JS_DEBUGGER); + } + }); } }); diff --git a/toolkit/devtools/canvasdebugger/canvasdebugger.js b/toolkit/devtools/canvasdebugger/canvasdebugger.js index bb027c57fb..f0a1145fbf 100644 --- a/toolkit/devtools/canvasdebugger/canvasdebugger.js +++ b/toolkit/devtools/canvasdebugger/canvasdebugger.js @@ -12,7 +12,8 @@ Cu.import("resource://gre/modules/devtools/ViewHelpers.jsm"); Cu.import("resource://gre/modules/devtools/Console.jsm"); Cu.import("resource://gre/modules/devtools/gDevTools.jsm"); -const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require; +const devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; +const { require } = devtools; const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise; const EventEmitter = require("devtools/toolkit/event-emitter"); const { CallWatcherFront } = require("devtools/server/actors/call-watcher"); @@ -350,32 +351,3 @@ function getThumbnailForCall(thumbnails, index) { } return CanvasFront.INVALID_SNAPSHOT_IMAGE; } - -/** - * Opens/selects the debugger in this toolbox and jumps to the specified - * file name and line number. - */ -function viewSourceInDebugger(url, line) { - let showSource = ({ DebuggerView }) => { - let item = DebuggerView.Sources.getItemForAttachment(a => a.source.url === url); - if (item) { - DebuggerView.setEditorLocation(item.attachment.source.actor, line, { noDebug: true }).then(() => { - window.emit(EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER); - }, () => { - window.emit(EVENTS.SOURCE_NOT_FOUND_IN_JS_DEBUGGER); - }); - } - } - - // If the Debugger was already open, switch to it and try to show the - // source immediately. Otherwise, initialize it and wait for the sources - // to be added first. - let debuggerAlreadyOpen = gToolbox.getPanel("jsdebugger"); - gToolbox.selectTool("jsdebugger").then(({ panelWin: dbg }) => { - if (debuggerAlreadyOpen) { - showSource(dbg); - } else { - dbg.once(dbg.EVENTS.SOURCES_ADDED, () => showSource(dbg)); - } - }); -} diff --git a/toolkit/devtools/canvasdebugger/snapshotslist.js b/toolkit/devtools/canvasdebugger/snapshotslist.js index 7c8305f7ea..e8bd47e0d5 100644 --- a/toolkit/devtools/canvasdebugger/snapshotslist.js +++ b/toolkit/devtools/canvasdebugger/snapshotslist.js @@ -240,7 +240,7 @@ let SnapshotsListView = Heritage.extend(WidgetMethods, { // the dummy snapshot item from being drawn. this.addSnapshot(); - // If this is the first item, immediately show the "Loading?? notice. + // If this is the first item, immediately show the "Loading…" notice. if (this.itemCount == 1) { $("#empty-notice").hidden = true; $("#waiting-notice").hidden = false; @@ -463,7 +463,7 @@ let SnapshotsListView = Heritage.extend(WidgetMethods, { let footer = $(".snapshot-item-footer", snapshotItem.target); let save = $(".snapshot-item-save", snapshotItem.target); - // Show a throbber and a "Saving?? label if serializing isn't immediate. + // Show a throbber and a "Saving…" label if serializing isn't immediate. setNamedTimeout("call-list-save", CALLS_LIST_SLOW_SAVE_DELAY, () => { footer.classList.add("devtools-throbber"); save.setAttribute("disabled", "true"); diff --git a/toolkit/devtools/client/connection-manager.js b/toolkit/devtools/client/connection-manager.js index c4c0724ff6..e48cd7f4a8 100644 --- a/toolkit/devtools/client/connection-manager.js +++ b/toolkit/devtools/client/connection-manager.js @@ -17,6 +17,8 @@ Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); DevToolsUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); +const REMOTE_TIMEOUT = "devtools.debugger.remote-timeout"; + /** * Connection Manager. * @@ -52,6 +54,8 @@ DevToolsUtils.defineLazyModuleGetter(this, "Task", * . logs Current logs. "newlog" event notifies new available logs * . store Reference to a local data store (see below) * . keepConnecting Should the connection keep trying to connect? + * . timeoutDelay When should we give up (in ms)? + * 0 means wait forever. * . encryption Should the connection be encrypted? * . authentication What authentication scheme should be used? * . authenticator The |Authenticator| instance used. Overriding @@ -233,8 +237,11 @@ Connection.prototype = { return settings; }, + timeoutDelay: Services.prefs.getIntPref(REMOTE_TIMEOUT), + resetOptions() { this.keepConnecting = false; + this.timeoutDelay = Services.prefs.getIntPref(REMOTE_TIMEOUT); this.encryption = false; this.authentication = null; this.advertisement = null; @@ -268,8 +275,9 @@ Connection.prototype = { } this._setStatus(Connection.Status.CONNECTING); - let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout"); - this._timeoutID = setTimeout(this._onTimeout, delay); + if (this.timeoutDelay > 0) { + this._timeoutID = setTimeout(this._onTimeout, this.timeoutDelay); + } this._clientConnect(); } else { let msg = "Can't connect. Client is not fully disconnected"; diff --git a/toolkit/devtools/commandline/commands-index.js b/toolkit/devtools/commandline/commands-index.js index 3e3883488d..15b6efccc2 100644 --- a/toolkit/devtools/commandline/commands-index.js +++ b/toolkit/devtools/commandline/commands-index.js @@ -4,9 +4,56 @@ "use strict"; -const gcli = require("gcli/index"); +const { createSystem, connectFront, disconnectFront } = require("gcli/system"); +const { GcliFront } = require("devtools/server/actors/gcli"); -const commandModules = [ +/** + * This is the basic list of modules that should be loaded into each + * requisition instance whether server side or client side + */ +exports.baseModules = [ + "gcli/types/delegate", + "gcli/types/selection", + "gcli/types/array", + + "gcli/types/boolean", + "gcli/types/command", + "gcli/types/date", + "gcli/types/file", + "gcli/types/javascript", + "gcli/types/node", + "gcli/types/number", + "gcli/types/resource", + "gcli/types/setting", + "gcli/types/string", + "gcli/types/union", + "gcli/types/url", + + "gcli/fields/fields", + "gcli/fields/delegate", + "gcli/fields/selection", + + "gcli/ui/focus", + "gcli/ui/intro", + + "gcli/converters/converters", + "gcli/converters/basic", + "gcli/converters/terminal", + + "gcli/languages/command", + "gcli/languages/javascript", + + "gcli/commands/clear", + "gcli/commands/context", + "gcli/commands/help", + "gcli/commands/pref", +]; + +/** + * Some commands belong to a tool (see getToolModules). This is a list of the + * modules that are *not* owned by a tool. + */ +exports.devtoolsModules = [ "devtools/tilt/tilt-commands", "gcli/commands/addon", "gcli/commands/appcache", @@ -29,15 +76,83 @@ const commandModules = [ "gcli/commands/tools", ]; -gcli.addItemsByModule(commandModules, { delayedLoad: true }); +/** + * Register commands from tools with 'command: [ "some/module" ]' definitions. + * The map/reduce incantation squashes the array of arrays to a single array. + */ +const defaultTools = require("definitions").defaultTools; +exports.devtoolsToolModules = defaultTools.map(def => def.commands || []) + .reduce((prev, curr) => prev.concat(curr), []); -const defaultTools = require("main").defaultTools; -for (let definition of defaultTools) { - if (definition.commands) { - gcli.addItemsByModule(definition.commands, { delayedLoad: true }); +/** + * Add modules to a system for use in a content process (but don't call load) + */ +exports.addAllItemsByModule = function(system) { + system.addItemsByModule(exports.baseModules, { delayedLoad: true }); + system.addItemsByModule(exports.devtoolsModules, { delayedLoad: true }); + system.addItemsByModule(exports.devtoolsToolModules, { delayedLoad: true }); + + const { mozDirLoader } = require("gcli/commands/cmd"); + system.addItemsByModule("mozcmd", { delayedLoad: true, loader: mozDirLoader }); +}; + +/** + * This is WeakMap where Links is an object that looks like + * { refs: number, promise: Promise, front: GcliFront } + */ +var linksForTarget = new WeakMap(); + +/** + * The toolbox uses the following properties on a command to allow it to be + * added to the toolbox toolbar + */ +var customProperties = [ "buttonId", "buttonClass", "tooltipText" ]; + +/** + * Create a system which connects to a GCLI in a remote target + * @return Promise for the given target + */ +exports.getSystem = function(target) { + const existingLinks = linksForTarget.get(target); + if (existingLinks != null) { + existingLinks.refs++; + return existingLinks.promise; } -} -const { mozDirLoader } = require("gcli/commands/cmd"); + const system = createSystem({ location: "client" }); -gcli.addItemsByModule("mozcmd", { delayedLoad: true, loader: mozDirLoader }); + exports.addAllItemsByModule(system); + + // Load the client system + const links = { + refs: 1, + system, + promise: system.load().then(() => { + return GcliFront.create(target).then(front => { + links.front = front; + return connectFront(system, front, customProperties).then(() => system); + }); + }) + }; + + linksForTarget.set(target, links); + return links.promise; +}; + +/** + * Someone that called getSystem doesn't need it any more, so decrement the + * count of users of the system for that target, and destroy if needed + */ +exports.releaseSystem = function(target) { + const links = linksForTarget.get(target); + if (links == null) { + throw new Error("releaseSystem called for unknown target"); + } + + links.refs--; + if (links.refs === 0) { + disconnectFront(links.system, links.front); + links.system.destroy(); + linksForTarget.delete(target); + } +}; diff --git a/toolkit/devtools/commandline/test/browser_cmd_addon.js b/toolkit/devtools/commandline/test/browser_cmd_addon.js index 14fb93e441..cd07c9e07b 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_addon.js +++ b/toolkit/devtools/commandline/test/browser_cmd_addon.js @@ -7,7 +7,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab("about:blank"); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_appcache_invalid.js b/toolkit/devtools/commandline/test/browser_cmd_appcache_invalid.js index 15cade68a6..d0e0a7fe88 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_appcache_invalid.js +++ b/toolkit/devtools/commandline/test/browser_cmd_appcache_invalid.js @@ -11,7 +11,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let lines = [ 'Manifest has a character encoding of ISO-8859-1. Manifests must have the ' + 'utf-8 character encoding.', diff --git a/toolkit/devtools/commandline/test/browser_cmd_appcache_valid.js b/toolkit/devtools/commandline/test/browser_cmd_appcache_valid.js index e9a11ead37..6643f93f4d 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_appcache_valid.js +++ b/toolkit/devtools/commandline/test/browser_cmd_appcache_valid.js @@ -10,7 +10,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_calllog.js b/toolkit/devtools/commandline/test/browser_cmd_calllog.js index 2ca225e3d5..85a7e378ed 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_calllog.js +++ b/toolkit/devtools/commandline/test/browser_cmd_calllog.js @@ -8,7 +8,7 @@ const TEST_URI = "data:text/html;charset=utf-8,gcli-calllog"; let tests = {}; function test() { - return Task.spawn(function() { + return Task.spawn(function*() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_calllog_chrome.js b/toolkit/devtools/commandline/test/browser_cmd_calllog_chrome.js index 1bc9d61068..066588f994 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_calllog_chrome.js +++ b/toolkit/devtools/commandline/test/browser_cmd_calllog_chrome.js @@ -8,7 +8,7 @@ const TEST_URI = "data:text/html;charset=utf-8,cmd-calllog-chrome"; let tests = {}; function test() { - return Task.spawn(function() { + return Task.spawn(function*() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_commands.js b/toolkit/devtools/commandline/test/browser_cmd_commands.js index 78dc0a4886..8ba0988ccb 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_commands.js +++ b/toolkit/devtools/commandline/test/browser_cmd_commands.js @@ -9,7 +9,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); @@ -49,7 +49,7 @@ function spawnTest() { yield helpers.audit(options, [ { setup: "console close", - exec: { output: true } + exec: { output: "" } } ]); diff --git a/toolkit/devtools/commandline/test/browser_cmd_csscoverage_startstop.js b/toolkit/devtools/commandline/test/browser_cmd_csscoverage_startstop.js index f1527c78be..ad03364319 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_csscoverage_startstop.js +++ b/toolkit/devtools/commandline/test/browser_cmd_csscoverage_startstop.js @@ -33,18 +33,21 @@ add_task(function*() { * Visit all the pages in the test */ function* navigate(usage, options) { - yield usage.start(); + yield usage.start(options.chromeWindow, options.target); ok(usage.isRunning(), "csscoverage is running"); + let load1Promise = helpers.listenOnce(options.browser, "load", true); + yield helpers.navigate(PAGE_1, options); // Wait for the test pages to auto-cycle - let ev = yield helpers.listenOnce(options.browser, "load", true); - is(ev.target.location.href, PAGE_1, "page 1 loaded"); + yield load1Promise; + is(options.window.location.href, PAGE_1, "page 1 loaded"); - ev = yield helpers.listenOnce(options.browser, "load", true); - is(ev.target.location.href, PAGE_3, "page 3 loaded"); + // Page 2 is a frame in page 1. JS in the page navigates to page 3. + yield helpers.listenOnce(options.browser, "load", true); + is(options.window.location.href, PAGE_3, "page 3 loaded"); yield usage.stop(); diff --git a/toolkit/devtools/commandline/test/browser_cmd_jsb.js b/toolkit/devtools/commandline/test/browser_cmd_jsb.js index cf2a9da13f..146d1f99da 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_jsb.js +++ b/toolkit/devtools/commandline/test/browser_cmd_jsb.js @@ -10,7 +10,7 @@ function test() { return Task.spawn(testTask).then(finish, helpers.handleError); } -function testTask() { +function* testTask() { let options = yield helpers.openTab("about:blank"); yield helpers.openToolbar(options); @@ -29,7 +29,10 @@ function testTask() { { setup: 'jsb ' + TEST_URI, // Should result in a new scratchpad window - exec: { } + exec: { + output: '', + error: false + } } ]); diff --git a/toolkit/devtools/commandline/test/browser_cmd_media.js b/toolkit/devtools/commandline/test/browser_cmd_media.js index 41973c3f89..c4bb3fe4b9 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_media.js +++ b/toolkit/devtools/commandline/test/browser_cmd_media.js @@ -74,7 +74,7 @@ let tests = { }; function test() { - return Task.spawn(function() { + return Task.spawn(function*() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_pagemod_export.js b/toolkit/devtools/commandline/test/browser_cmd_pagemod_export.js index c405a29c72..3d4cefcc35 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_pagemod_export.js +++ b/toolkit/devtools/commandline/test/browser_cmd_pagemod_export.js @@ -10,7 +10,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); @@ -302,7 +302,8 @@ function spawnTest() { args: { searchAttributes: { value: undefined, status: 'INCOMPLETE' }, searchElements: { value: undefined, status: 'INCOMPLETE' }, - root: { value: undefined }, + // root: { value: undefined }, // 'root' is a node which is remote + // so we can't see the value in tests ignoreCase: { value: false }, } }, @@ -317,7 +318,8 @@ function spawnTest() { args: { searchAttributes: { value: 'foo' }, searchElements: { value: 'bar' }, - root: { value: undefined }, + // root: { value: undefined }, // 'root' is a node which is remote + // so we can't see the value in tests ignoreCase: { value: false }, } }, diff --git a/toolkit/devtools/commandline/test/browser_cmd_pref1.js b/toolkit/devtools/commandline/test/browser_cmd_pref1.js index 4e2aa41e59..0c059eeb4b 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_pref1.js +++ b/toolkit/devtools/commandline/test/browser_cmd_pref1.js @@ -13,7 +13,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_pref2.js b/toolkit/devtools/commandline/test/browser_cmd_pref2.js index 74ed916a3c..64dafbf92d 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_pref2.js +++ b/toolkit/devtools/commandline/test/browser_cmd_pref2.js @@ -13,7 +13,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_pref3.js b/toolkit/devtools/commandline/test/browser_cmd_pref3.js index fea31d9487..073eb9268c 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_pref3.js +++ b/toolkit/devtools/commandline/test/browser_cmd_pref3.js @@ -16,7 +16,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { let options = yield helpers.openTab(TEST_URI); yield helpers.openToolbar(options); diff --git a/toolkit/devtools/commandline/test/browser_cmd_screenshot.js b/toolkit/devtools/commandline/test/browser_cmd_screenshot.js index 437daa99f8..bf0726c946 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_screenshot.js +++ b/toolkit/devtools/commandline/test/browser_cmd_screenshot.js @@ -11,7 +11,7 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { waitForExplicitFinish(); info("RUN TEST: non-private window"); @@ -81,11 +81,6 @@ function addTabWithToolbarRunTests(win) { input: 'screenshot --selector img#testImage', markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV', status: 'VALID', - args: { - selector: { - value: options.window.document.getElementById("testImage") - }, - } }, }, ]); diff --git a/toolkit/devtools/commandline/test/browser_cmd_settings.js b/toolkit/devtools/commandline/test/browser_cmd_settings.js index 8b4e27225b..fa9cee0f0d 100644 --- a/toolkit/devtools/commandline/test/browser_cmd_settings.js +++ b/toolkit/devtools/commandline/test/browser_cmd_settings.js @@ -16,14 +16,18 @@ function test() { return Task.spawn(spawnTest).then(finish, helpers.handleError); } -function spawnTest() { +function* spawnTest() { // Setup let options = yield helpers.openTab(TEST_URI); - require("devtools/commandline/commands-index"); - let gcli = require("gcli/index"); - yield gcli.load(); - let settings = gcli.settings; + const { createSystem } = require("gcli/system"); + const system = createSystem({ location: "server" }); + + const gcliInit = require("devtools/commandline/commands-index"); + gcliInit.addAllItemsByModule(system); + yield system.load(); + + let settings = system.settings; let hideIntroEnabled = settings.get("devtools.gcli.hideIntro"); let tabSize = settings.get("devtools.editor.tabsize"); diff --git a/toolkit/devtools/commandline/test/browser_gcli_async.js b/toolkit/devtools/commandline/test/browser_gcli_async.js index 590bb2cc82..899a9124c4 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_async.js +++ b/toolkit/devtools/commandline/test/browser_gcli_async.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testAsync.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_async.js"); } -// - // var helpers = require('./helpers'); exports.testBasic = function(options) { @@ -74,7 +59,6 @@ exports.testBasic = function(options) { args: { command: { name: 'tsslow' }, hello: { - value: undefined, arg: '', status: 'INCOMPLETE' }, @@ -95,7 +79,6 @@ exports.testBasic = function(options) { args: { command: { name: 'tsslow' }, hello: { - value: undefined, arg: ' S', status: 'INCOMPLETE' }, @@ -116,7 +99,6 @@ exports.testBasic = function(options) { args: { command: { name: 'tsslow' }, hello: { - value: 'Shalom', arg: ' Shalom ', status: 'VALID', message: '' diff --git a/toolkit/devtools/commandline/test/browser_gcli_canon.js b/toolkit/devtools/commandline/test/browser_gcli_canon.js index 613e5b2d4b..fe6900fb87 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_canon.js +++ b/toolkit/devtools/commandline/test/browser_gcli_canon.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testCanon.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_canon.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); var Commands = require('gcli/commands/commands').Commands; @@ -219,6 +204,9 @@ exports.testAltCommands = function(options) { { name: 'num', type: 'number' }, { name: 'opt', type: { name: 'selection', data: [ '1', '2', '3' ] } }, ], + customProp1: 'localValue', + customProp2: true, + customProp3: 42, exec: function(args, context) { return context.commandName + ':' + args.str + ':' + args.num + ':' + args.opt; @@ -235,6 +223,24 @@ exports.testAltCommands = function(options) { '],"isParent":false}]', 'JSON.stringify(commandSpecs)'); + var customProps = [ 'customProp1', 'customProp2', 'customProp3', ]; + var commandSpecs2 = altCommands.getCommandSpecs(customProps); + assert.is(JSON.stringify(commandSpecs2), + '[{' + + '"item":"command",' + + '"name":"tss",' + + '"params":[' + + '{"name":"str","type":"string"},' + + '{"name":"num","type":"number"},' + + '{"name":"opt","type":{"name":"selection","data":["1","2","3"]}}' + + '],' + + '"isParent":false,' + + '"customProp1":"localValue",' + + '"customProp2":true,' + + '"customProp3":42' + + '}]', + 'JSON.stringify(commandSpecs)'); + var remoter = function(args, context) { assert.is(context.commandName, 'tss', 'commandName is tss'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_cli1.js b/toolkit/devtools/commandline/test/browser_gcli_cli1.js index cb4d52e7af..e60bb37a12 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_cli1.js +++ b/toolkit/devtools/commandline/test/browser_gcli_cli1.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testCli1.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_cli1.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); @@ -268,7 +253,6 @@ exports.testTsv = function(options) { } }, { - skipRemainingIf: options.isNoDom, name: '|tsv option', setup: function() { return helpers.setInput(options, 'tsv option', 0); diff --git a/toolkit/devtools/commandline/test/browser_gcli_cli2.js b/toolkit/devtools/commandline/test/browser_gcli_cli2.js index f1a0a9e989..ff787d2af4 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_cli2.js +++ b/toolkit/devtools/commandline/test/browser_gcli_cli2.js @@ -15,45 +15,18 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testCli2.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_cli2.js"); } -// - // var helpers = require('./helpers'); -var nodetype = require('gcli/types/node'); - -exports.setup = function(options) { - if (options.window) { - nodetype.setDocument(options.window.document); - } -}; - -exports.shutdown = function(options) { - nodetype.unsetDocument(); -}; - exports.testSingleString = function(options) { return helpers.audit(options, [ { @@ -376,7 +349,6 @@ exports.testSingleFloat = function(options) { } }, { - skipRemainingIf: options.isNoDom, name: 'tsf x (cursor=4)', setup: function() { return helpers.setInput(options, 'tsf x', 4); @@ -406,21 +378,14 @@ exports.testSingleFloat = function(options) { }; exports.testElementWeb = function(options) { - var inputElement = options.isNoDom ? - null : - options.window.document.getElementById('gcli-input'); - return helpers.audit(options, [ { - skipIf: function gcliInputElementExists() { - return inputElement == null; - }, - setup: 'tse #gcli-input', + setup: 'tse #gcli-root', check: { - input: 'tse #gcli-input', + input: 'tse #gcli-root', hints: ' [options]', - markup: 'VVVVVVVVVVVVVVV', - cursor: 15, + markup: 'VVVVVVVVVVVVVV', + cursor: 14, current: 'node', status: 'VALID', predictions: [ ], @@ -428,8 +393,7 @@ exports.testElementWeb = function(options) { args: { command: { name: 'tse' }, node: { - value: inputElement, - arg: ' #gcli-input', + arg: ' #gcli-root', status: 'VALID', message: '' }, @@ -444,7 +408,6 @@ exports.testElementWeb = function(options) { exports.testElement = function(options) { return helpers.audit(options, [ { - skipRemainingIf: options.isNoDom, setup: 'tse', check: { input: 'tse', @@ -457,7 +420,7 @@ exports.testElement = function(options) { unassigned: [ ], args: { command: { name: 'tse' }, - node: { value: undefined, arg: '', status: 'INCOMPLETE' }, + node: { arg: '', status: 'INCOMPLETE' }, nodes: { arg: '', status: 'VALID', message: '' }, nodes2: { arg: '', status: 'VALID', message: '' }, } @@ -605,7 +568,7 @@ exports.testNestedCommand = function(options) { } }, { - skipIf: options.isPhantomjs, + skipIf: options.isPhantomjs, // PhantomJS gets predictions wrong setup: 'tsn x', check: { input: 'tsn x', diff --git a/toolkit/devtools/commandline/test/browser_gcli_completion1.js b/toolkit/devtools/commandline/test/browser_gcli_completion1.js index 0df796265b..8478ebf71f 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_completion1.js +++ b/toolkit/devtools/commandline/test/browser_gcli_completion1.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testCompletion1.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_completion1.js"); } -// - // var helpers = require('./helpers'); exports.testActivate = function(options) { @@ -183,7 +168,7 @@ exports.testActivate = function(options) { } }, { - skipIf: options.isPhantomjs, + skipIf: options.isPhantomjs, // PhantomJS gets predictions wrong setup: 'tsg d', check: { hints: ' [options] -> ccc' diff --git a/toolkit/devtools/commandline/test/browser_gcli_completion2.js b/toolkit/devtools/commandline/test/browser_gcli_completion2.js index b27b8e7478..38e88f28ae 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_completion2.js +++ b/toolkit/devtools/commandline/test/browser_gcli_completion2.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testCompletion2.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_completion2.js"); } -// - // var helpers = require('./helpers'); exports.testLong = function(options) { @@ -170,7 +155,6 @@ exports.testNoTab = function(options) { } }, { - skipIf: options.isNoDom, name: '', setup: function() { // Doing it this way avoids clearing the input buffer diff --git a/toolkit/devtools/commandline/test/browser_gcli_context.js b/toolkit/devtools/commandline/test/browser_gcli_context.js index 1aed2851ef..78993ae176 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_context.js +++ b/toolkit/devtools/commandline/test/browser_gcli_context.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testContext.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_context.js"); } -// - // var helpers = require('./helpers'); exports.testBaseline = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_date.js b/toolkit/devtools/commandline/test/browser_gcli_date.js index 352679cc1f..1fed8b0f3a 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_date.js +++ b/toolkit/devtools/commandline/test/browser_gcli_date.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testDate.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_date.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); @@ -66,15 +51,15 @@ exports.testMaxMin = function(options) { var date = types.createType({ name: 'date', max: max, min: min }); assert.is(date.getMax(), max, 'max setup'); - var incremented = date.increment(min); + var incremented = date.nudge(min, 1); assert.is(incremented, max, 'incremented'); }; exports.testIncrement = function(options) { var date = options.requisition.system.types.createType('date'); return date.parseString('now').then(function(conversion) { - var plusOne = date.increment(conversion.value); - var minusOne = date.decrement(plusOne); + var plusOne = date.nudge(conversion.value, 1); + var minusOne = date.nudge(plusOne, -1); // See comments in testParse var gap = new Date().getTime() - minusOne.getTime(); @@ -126,7 +111,7 @@ exports.testInput = function(options) { }, exec: { output: [ /^Exec: tsdate/, /2001/, /1980/ ], - type: 'string', + type: 'testCommandOutput', error: false } }, @@ -172,7 +157,7 @@ exports.testInput = function(options) { }, exec: { output: [ /^Exec: tsdate/, /2001/, /1980/ ], - type: 'string', + type: 'testCommandOutput', error: false } }, @@ -213,7 +198,7 @@ exports.testInput = function(options) { }, exec: { output: [ /^Exec: tsdate/, new Date().getFullYear() ], - type: 'string', + type: 'testCommandOutput', error: false } }, @@ -253,7 +238,7 @@ exports.testInput = function(options) { }, exec: { output: [ /^Exec: tsdate/, new Date().getFullYear() ], - type: 'string', + type: 'testCommandOutput', error: false } } @@ -264,7 +249,7 @@ exports.testIncrDecr = function(options) { return helpers.audit(options, [ { // createRequisitionAutomator doesn't fake UP/DOWN well enough - skipRemainingIf: options.isNoDom, + skipRemainingIf: options.isNode, setup: 'tsdate 2001-01-01', check: { input: 'tsdate 2001-01-02', diff --git a/toolkit/devtools/commandline/test/browser_gcli_exec.js b/toolkit/devtools/commandline/test/browser_gcli_exec.js index 0b1f47ddc3..feb7bb03e1 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_exec.js +++ b/toolkit/devtools/commandline/test/browser_gcli_exec.js @@ -15,54 +15,18 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testExec.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_exec.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); -var nodetype = require('gcli/types/node'); - -var mockBody = { - style: {} -}; - -var mockEmptyNodeList = { - length: 0, - item: function() { return null; } -}; - -var mockRootNodeList = { - length: 1, - item: function(i) { return mockBody; } -}; - -var mockDoc = { - querySelectorAll: function(css) { - return (css === ':root') ? mockRootNodeList : mockEmptyNodeList; - } -}; exports.testParamGroup = function(options) { var tsg = options.requisition.system.commands.get('tsg'); @@ -121,7 +85,7 @@ exports.testWithHelpers = function(options) { } }, exec: { - output: 'Exec: tsv optionType=string, optionValue=10' + output: 'Exec: tsv optionType=option1 optionValue=10' } }, { @@ -151,7 +115,7 @@ exports.testWithHelpers = function(options) { } }, exec: { - output: 'Exec: tsv optionType=number, optionValue=10' + output: 'Exec: tsv optionType=option2 optionValue=10' } }, // Delegated remote types can't transfer value types so we only test for @@ -163,7 +127,7 @@ exports.testWithHelpers = function(options) { args: { optionValue: { value: '10' } } }, exec: { - output: 'Exec: tsv optionType=string, optionValue=10' + output: 'Exec: tsv optionType=option1 optionValue=10' } }, { @@ -173,7 +137,7 @@ exports.testWithHelpers = function(options) { args: { optionValue: { value: 10 } } }, exec: { - output: 'Exec: tsv optionType=number, optionValue=10' + output: 'Exec: tsv optionType=option2 optionValue=10' } } ]); @@ -228,7 +192,7 @@ exports.testExecText = function(options) { } }, exec: { - output: 'Exec: tsr text=fred bloggs' + output: 'Exec: tsr text=fred\\ bloggs' } }, { @@ -253,7 +217,7 @@ exports.testExecText = function(options) { } }, exec: { - output: 'Exec: tsr text=fred bloggs' + output: 'Exec: tsr text=fred\\ bloggs' } }, { @@ -278,7 +242,7 @@ exports.testExecText = function(options) { } }, exec: { - output: 'Exec: tsr text=fred bloggs' + output: 'Exec: tsr text=fred\\ bloggs' } } ]); @@ -403,7 +367,6 @@ exports.testExecScript = function(options) { args: { command: { name: 'tsj' }, javascript: { - value: '1 + 1', arg: ' { 1 + 1 }', status: 'VALID', message: '' @@ -418,12 +381,9 @@ exports.testExecScript = function(options) { }; exports.testExecNode = function(options) { - var origDoc = nodetype.getDocument(); - nodetype.setDocument(mockDoc); - return helpers.audit(options, [ { - skipIf: options.isNoDom, + skipIf: options.isRemote, setup: 'tse :root', check: { input: 'tse :root', @@ -437,19 +397,16 @@ exports.testExecNode = function(options) { args: { command: { name: 'tse' }, node: { - value: mockBody, arg: ' :root', status: 'VALID', message: '' }, nodes: { - value: mockEmptyNodeList, arg: '', status: 'VALID', message: '' }, nodes2: { - value: mockEmptyNodeList, arg: '', status: 'VALID', message: '' @@ -459,8 +416,10 @@ exports.testExecNode = function(options) { exec: { output: /^Exec: tse/ }, - post: function() { - nodetype.setDocument(origDoc); + post: function(output) { + assert.is(output.data.args.node, ':root', 'node should be :root'); + assert.is(output.data.args.nodes, 'Error', 'nodes should be Error'); + assert.is(output.data.args.nodes2, 'Error', 'nodes2 should be Error'); } } ]); @@ -552,7 +511,7 @@ exports.testExecArray = function(options) { } }, exec: { - output: 'Exec: tselarr num=1, arr=' + output: 'Exec: tselarr num=1 arr=' } }, { @@ -573,7 +532,7 @@ exports.testExecArray = function(options) { } }, exec: { - output: 'Exec: tselarr num=1, arr=a' + output: 'Exec: tselarr num=1 arr=a' } }, { @@ -594,7 +553,7 @@ exports.testExecArray = function(options) { } }, exec: { - output: 'Exec: tselarr num=1, arr=a,b' + output: 'Exec: tselarr num=1 arr=a b' } } ]); @@ -621,7 +580,7 @@ exports.testExecMultiple = function(options) { } }, exec: { - output: 'Exec: tsm abc=a, txt=10, num=10' + output: 'Exec: tsm abc=a txt=10 num=10' } } ]); @@ -651,9 +610,47 @@ exports.testExecDefaults = function(options) { } }, exec: { - output: 'Exec: tsg solo=aaa, txt1=null, bool=false, txt2=d, num=42' + output: 'Exec: tsg solo=aaa txt1= bool=false txt2=d num=42' + } + } + ]); +}; + +exports.testNested = function(options) { + var commands = options.requisition.system.commands; + commands.add({ + name: 'nestorama', + exec: function(args, context) { + return context.updateExec('tsb').then(function(tsbOutput) { + return context.updateExec('tsu 6').then(function(tsuOutput) { + return JSON.stringify({ + tsb: tsbOutput.data, + tsu: tsuOutput.data + }); + }); + }); + } + }); + + return helpers.audit(options, [ + { + setup: 'nestorama', + exec: { + output: + '{' + + '"tsb":{' + + '"name":"tsb",' + + '"args":{"toggle":"false"}' + + '},' + + '"tsu":{' + + '"name":"tsu",' + + '"args":{"num":"6"}' + + '}' + + '}' + }, + post: function() { + commands.remove('nestorama'); } } ]); - }; diff --git a/toolkit/devtools/commandline/test/browser_gcli_fail.js b/toolkit/devtools/commandline/test/browser_gcli_fail.js index c0b94f4925..b2a502ef93 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_fail.js +++ b/toolkit/devtools/commandline/test/browser_gcli_fail.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testFail.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_fail.js"); } -// - // var helpers = require('./helpers'); exports.testBasic = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_file.js b/toolkit/devtools/commandline/test/browser_gcli_file.js index 1317d9c7da..c6cf73cd1b 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_file.js +++ b/toolkit/devtools/commandline/test/browser_gcli_file.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testFile.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_file.js"); } -// - // var helpers = require('./helpers'); var local = false; @@ -47,10 +32,7 @@ var local = false; exports.testBasic = function(options) { return helpers.audit(options, [ { - // These tests require us to be using node directly or to be in - // PhantomJS connected to an execute enabled node server or to be in - // firefox. - skipRemainingIf: options.isPhantomjs || options.isFirefox, + skipRemainingIf: options.isFirefox, // No file implementation in Firefox setup: 'tsfile open /', check: { input: 'tsfile open /', diff --git a/toolkit/devtools/commandline/test/browser_gcli_fileparser.js b/toolkit/devtools/commandline/test/browser_gcli_fileparser.js index 219b793a92..17508b8abb 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_fileparser.js +++ b/toolkit/devtools/commandline/test/browser_gcli_fileparser.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testFileparser.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_fileparser.js"); } -// - // var assert = require('../testharness/assert'); var fileparser = require('gcli/util/fileparser'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_filesystem.js b/toolkit/devtools/commandline/test/browser_gcli_filesystem.js index 23c8dda28d..1b6d28bf44 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_filesystem.js +++ b/toolkit/devtools/commandline/test/browser_gcli_filesystem.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testFilesystem.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_filesystem.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); var filesystem = require('gcli/util/filesystem'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_focus.js b/toolkit/devtools/commandline/test/browser_gcli_focus.js index 48def8195f..47b8ea35df 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_focus.js +++ b/toolkit/devtools/commandline/test/browser_gcli_focus.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testFocus.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_focus.js"); } -// - // var helpers = require('./helpers'); exports.testBasic = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_history.js b/toolkit/devtools/commandline/test/browser_gcli_history.js index 590353cbee..7b34b73ed6 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_history.js +++ b/toolkit/devtools/commandline/test/browser_gcli_history.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testHistory.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_history.js"); } -// - // var assert = require('../testharness/assert'); var History = require('gcli/ui/history').History; diff --git a/toolkit/devtools/commandline/test/browser_gcli_incomplete.js b/toolkit/devtools/commandline/test/browser_gcli_incomplete.js index c443bbd49a..2a089a93c2 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_incomplete.js +++ b/toolkit/devtools/commandline/test/browser_gcli_incomplete.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testIncomplete.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_incomplete.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_inputter.js b/toolkit/devtools/commandline/test/browser_gcli_inputter.js index e8d1c214a2..f56ecc0ab7 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_inputter.js +++ b/toolkit/devtools/commandline/test/browser_gcli_inputter.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testInputter.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_inputter.js"); } -// - // var assert = require('../testharness/assert'); var KeyEvent = require('gcli/util/util').KeyEvent; @@ -89,7 +74,7 @@ exports.testOutput = function(options) { var ev1 = { keyCode: KeyEvent.DOM_VK_RETURN }; return terminal.handleKeyUp(ev1).then(function() { assert.ok(latestEvent != null, 'events this test'); - assert.is(latestData, 'Exec: tss ', 'last command is tss'); + assert.is(latestData.name, 'tss', 'last command is tss'); assert.is(terminal.getInputState().typed, '', diff --git a/toolkit/devtools/commandline/test/browser_gcli_intro.js b/toolkit/devtools/commandline/test/browser_gcli_intro.js index 263000e891..1d5ff2e8f4 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_intro.js +++ b/toolkit/devtools/commandline/test/browser_gcli_intro.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testIntro.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_intro.js"); } -// - // var helpers = require('./helpers'); exports.testIntroStatus = function(options) { @@ -67,7 +52,6 @@ exports.testIntroStatus = function(options) { }, { setup: 'intro', - skipIf: options.isNoDom, check: { typed: 'intro', markup: 'VVVVV', diff --git a/toolkit/devtools/commandline/test/browser_gcli_js.js b/toolkit/devtools/commandline/test/browser_gcli_js.js index 4128c46422..06424488ae 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_js.js +++ b/toolkit/devtools/commandline/test/browser_gcli_js.js @@ -15,73 +15,55 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testJs.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_js.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); -var javascript = require('gcli/types/javascript'); - -var tempWindow; exports.setup = function(options) { - if (options.isNoDom) { + if (jsTestDisallowed(options)) { return; } - tempWindow = javascript.getGlobalObject(); - Object.defineProperty(options.window, 'donteval', { + // Check that we're not trespassing on 'donteval' + var win = options.requisition.environment.window; + Object.defineProperty(win, 'donteval', { get: function() { assert.ok(false, 'donteval should not be used'); + console.trace(); return { cant: '', touch: '', 'this': '' }; }, enumerable: true, - configurable : true + configurable: true }); - javascript.setGlobalObject(options.window); }; exports.shutdown = function(options) { - if (options.isNoDom) { + if (jsTestDisallowed(options)) { return; } - javascript.setGlobalObject(tempWindow); - tempWindow = undefined; - delete options.window.donteval; + delete options.requisition.environment.window.donteval; }; -function jsTestAllowed(options) { - return options.isRemote || options.isNoDom || +function jsTestDisallowed(options) { + return options.isRemote || // Altering the environment (which isn't remoted) + options.isNode || options.requisition.system.commands.get('{') == null; } exports.testBasic = function(options) { return helpers.audit(options, [ { - skipRemainingIf: jsTestAllowed, + skipRemainingIf: jsTestDisallowed, setup: '{', check: { input: '{', @@ -236,7 +218,7 @@ exports.testBasic = function(options) { exports.testDocument = function(options) { return helpers.audit(options, [ { - skipRemainingIf: jsTestAllowed, + skipRemainingIf: jsTestDisallowed, setup: '{ docu', check: { input: '{ docu', @@ -315,7 +297,8 @@ exports.testDocument = function(options) { command: { name: '{' }, javascript: { value: 'document.title', - arg: '{ document.title ', + // arg: '{ document.title ', + // Node/JSDom gets this wrong and omits the trailing space. Why? status: 'VALID', message: '' } @@ -348,14 +331,9 @@ exports.testDocument = function(options) { }; exports.testDonteval = function(options) { - if (!options.isNoDom) { - // nodom causes an eval here, maybe that's node/v8? - assert.ok('donteval' in options.window, 'donteval exists'); - } - return helpers.audit(options, [ { - skipRemainingIf: jsTestAllowed, + skipRemainingIf: true, // Commented out until we fix non-enumerable props setup: '{ don', check: { input: '{ don', @@ -476,7 +454,7 @@ exports.testDonteval = function(options) { exports.testExec = function(options) { return helpers.audit(options, [ { - skipRemainingIf: jsTestAllowed, + skipRemainingIf: jsTestDisallowed, setup: '{ 1+1', check: { input: '{ 1+1', diff --git a/toolkit/devtools/commandline/test/browser_gcli_keyboard1.js b/toolkit/devtools/commandline/test/browser_gcli_keyboard1.js index 0de7794914..78e25b370b 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_keyboard1.js +++ b/toolkit/devtools/commandline/test/browser_gcli_keyboard1.js @@ -15,46 +15,19 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testKeyboard1.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_keyboard1.js"); } -// - var javascript = require('gcli/types/javascript'); // var helpers = require('./helpers'); -var tempWindow; - -exports.setup = function(options) { - tempWindow = javascript.getGlobalObject(); - javascript.setGlobalObject(options.window); -}; - -exports.shutdown = function(options) { - javascript.setGlobalObject(tempWindow); - tempWindow = undefined; -}; - exports.testSimple = function(options) { return helpers.audit(options, [ { @@ -75,16 +48,12 @@ exports.testSimple = function(options) { exports.testScript = function(options) { return helpers.audit(options, [ { - skipIf: function commandJsMissing() { - return options.requisition.system.commands.get('{') == null; - }, + skipRemainingIf: options.isRemote || + options.requisition.system.commands.get('{') == null, setup: '{ wind', check: { input: '{ window' } }, { - skipIf: function commandJsMissing() { - return options.requisition.system.commands.get('{') == null; - }, setup: '{ window.docum', check: { input: '{ window.document' } } @@ -94,9 +63,8 @@ exports.testScript = function(options) { exports.testJsdom = function(options) { return helpers.audit(options, [ { - skipIf: function jsDomOrCommandJsMissing() { - return options.requisition.system.commands.get('{') == null; - }, + skipIf: options.isRemote || + options.requisition.system.commands.get('{') == null, setup: '{ window.document.titl', check: { input: '{ window.document.title ' } } diff --git a/toolkit/devtools/commandline/test/browser_gcli_keyboard2.js b/toolkit/devtools/commandline/test/browser_gcli_keyboard2.js index 7f510f08e5..35fc44668b 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_keyboard2.js +++ b/toolkit/devtools/commandline/test/browser_gcli_keyboard2.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testKeyboard2.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_keyboard2.js"); } -// - // var helpers = require('./helpers'); exports.testIncr = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_keyboard3.js b/toolkit/devtools/commandline/test/browser_gcli_keyboard3.js index c1bfc15fca..c3f38c9d75 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_keyboard3.js +++ b/toolkit/devtools/commandline/test/browser_gcli_keyboard3.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testKeyboard3.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_keyboard3.js"); } -// - // var helpers = require('./helpers'); exports.testDecr = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_keyboard4.js b/toolkit/devtools/commandline/test/browser_gcli_keyboard4.js index 5a358f4815..2558e2f82a 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_keyboard4.js +++ b/toolkit/devtools/commandline/test/browser_gcli_keyboard4.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testKeyboard4.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_keyboard4.js"); } -// - // var helpers = require('./helpers'); exports.testIncrFloat = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_keyboard5.js b/toolkit/devtools/commandline/test/browser_gcli_keyboard5.js index 41e36a4b90..0459bc0e16 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_keyboard5.js +++ b/toolkit/devtools/commandline/test/browser_gcli_keyboard5.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testKeyboard5.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_keyboard5.js"); } -// - // var helpers = require('./helpers'); exports.testCompleteDown = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_keyboard6.js b/toolkit/devtools/commandline/test/browser_gcli_keyboard6.js index d53a855b3f..06d81aae3a 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_keyboard6.js +++ b/toolkit/devtools/commandline/test/browser_gcli_keyboard6.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testKeyboard6.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_keyboard6.js"); } -// - // var helpers = require('./helpers'); exports.testCompleteUp = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_menu.js b/toolkit/devtools/commandline/test/browser_gcli_menu.js index 8e3eb167ff..a6eb25dcbf 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_menu.js +++ b/toolkit/devtools/commandline/test/browser_gcli_menu.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testMenu.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_menu.js"); } -// - // var helpers = require('./helpers'); exports.testOptions = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_node.js b/toolkit/devtools/commandline/test/browser_gcli_node.js index 7be07ba76a..7de891ba9e 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_node.js +++ b/toolkit/devtools/commandline/test/browser_gcli_node.js @@ -15,49 +15,22 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testNode.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_node.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); -var nodetype = require('gcli/types/node'); - -exports.setup = function(options) { - if (options.window) { - nodetype.setDocument(options.window.document); - } -}; - -exports.shutdown = function(options) { - nodetype.unsetDocument(); -}; exports.testNode = function(options) { return helpers.audit(options, [ { - skipRemainingIf: options.isNoDom, setup: 'tse ', check: { input: 'tse ', @@ -165,11 +138,8 @@ exports.testNode = function(options) { }; exports.testNodeDom = function(options) { - var requisition = options.requisition; - return helpers.audit(options, [ { - skipRemainingIf: options.isNoDom, setup: 'tse :root', check: { input: 'tse :root', @@ -202,10 +172,12 @@ exports.testNodeDom = function(options) { nodes2: { status: 'VALID' } } }, - post: function() { - assert.is(requisition.getAssignment('node').value.tagName, - 'HTML', - 'root id'); + exec: { + }, + post: function(output) { + if (!options.isRemote) { + assert.is(output.args.node.tagName, 'HTML', ':root tagName'); + } } }, { @@ -234,11 +206,8 @@ exports.testNodeDom = function(options) { }; exports.testNodes = function(options) { - var requisition = options.requisition; - return helpers.audit(options, [ { - skipRemainingIf: options.isNoDom, setup: 'tse :root --nodes *', check: { input: 'tse :root --nodes *', @@ -253,10 +222,18 @@ exports.testNodes = function(options) { nodes2: { status: 'VALID' } } }, - post: function() { - assert.is(requisition.getAssignment('node').value.tagName, - 'HTML', - '#gcli-input id'); + exec: { + }, + post: function(output) { + if (!options.isRemote) { + assert.is(output.args.node.tagName, 'HTML', ':root tagName'); + assert.ok(output.args.nodes.length > 3, 'nodes length'); + assert.is(output.args.nodes2.length, 0, 'nodes2 length'); + } + + assert.is(output.data.args.node, ':root', 'node data'); + assert.is(output.data.args.nodes, '*', 'nodes data'); + assert.is(output.data.args.nodes2, 'Error', 'nodes2 data'); } }, { @@ -275,10 +252,18 @@ exports.testNodes = function(options) { nodes2: { arg: ' --nodes2 div', status: 'VALID' } } }, - post: function() { - assert.is(requisition.getAssignment('node').value.tagName, - 'HTML', - 'root id'); + exec: { + }, + post: function(output) { + if (!options.isRemote) { + assert.is(output.args.node.tagName, 'HTML', ':root tagName'); + assert.is(output.args.nodes.length, 0, 'nodes length'); + assert.is(output.args.nodes2.item(0).tagName, 'DIV', 'div tagName'); + } + + assert.is(output.data.args.node, ':root', 'node data'); + assert.is(output.data.args.nodes, 'Error', 'nodes data'); + assert.is(output.data.args.nodes2, 'div', 'nodes2 data'); } }, { @@ -305,13 +290,6 @@ exports.testNodes = function(options) { }, nodes2: { arg: '', status: 'VALID', message: '' } } - }, - post: function() { - /* - assert.is(requisition.getAssignment('nodes2').value.constructor.name, - 'NodeList', - '#gcli-input id'); - */ } }, { @@ -333,16 +311,6 @@ exports.testNodes = function(options) { nodes: { arg: '', status: 'VALID', message: '' }, nodes2: { arg: ' --nodes2 ffff', status: 'VALID', message: '' } } - }, - post: function() { - /* - assert.is(requisition.getAssignment('nodes').value.constructor.name, - 'NodeList', - '#gcli-input id'); - assert.is(requisition.getAssignment('nodes2').value.constructor.name, - 'NodeList', - '#gcli-input id'); - */ } }, ]); diff --git a/toolkit/devtools/commandline/test/browser_gcli_pref1.js b/toolkit/devtools/commandline/test/browser_gcli_pref1.js index ee9c51d5e7..ceb875d66c 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_pref1.js +++ b/toolkit/devtools/commandline/test/browser_gcli_pref1.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testPref1.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_pref1.js"); } -// - // var helpers = require('./helpers'); exports.testPrefShowStatus = function(options) { @@ -67,7 +52,7 @@ exports.testPrefShowStatus = function(options) { setup: 'pref show ', check: { typed: 'pref show ', - hints: 'allowSet', + hints: 'eagerHelper', markup: 'VVVVVVVVVV', status: 'ERROR' } @@ -144,7 +129,7 @@ exports.testPrefSetStatus = function(options) { setup: 'pref set ', check: { typed: 'pref set ', - hints: 'allowSet ', + hints: 'eagerHelper ', markup: 'VVVVVVVVV', status: 'ERROR' } @@ -159,6 +144,7 @@ exports.testPrefSetStatus = function(options) { } }, { + skipIf: options.isRemote, setup: 'pref set tempTBool 4', check: { typed: 'pref set tempTBool 4', diff --git a/toolkit/devtools/commandline/test/browser_gcli_pref2.js b/toolkit/devtools/commandline/test/browser_gcli_pref2.js index 0192830774..5c4338fc9b 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_pref2.js +++ b/toolkit/devtools/commandline/test/browser_gcli_pref2.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testPref2.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_pref2.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); var mockSettings = require('./mockSettings'); @@ -55,10 +40,6 @@ exports.testPrefExec = function(options) { return; } - var allowSet = settings.getSetting('allowSet'); - var initialAllowSet = allowSet.value; - allowSet.value = false; - assert.is(mockSettings.tempNumber.value, 42, 'set to 42'); return helpers.audit(options, [ @@ -73,7 +54,6 @@ exports.testPrefExec = function(options) { } }, { - skipRemainingIf: options.isNoDom, setup: 'pref set tempNumber 4', check: { input: 'pref set tempNumber 4', @@ -98,16 +78,6 @@ exports.testPrefExec = function(options) { } } }, - exec: { - output: [ /void your warranty/, /I promise/ ] - }, - post: function() { - assert.is(mockSettings.tempNumber.value, 42, 'still set to 42'); - allowSet.value = true; - } - }, - { - setup: 'pref set tempNumber 4', exec: { output: '' }, @@ -128,8 +98,6 @@ exports.testPrefExec = function(options) { }, post: function() { assert.is(mockSettings.tempNumber.value, 42, 'reset to 42'); - - allowSet.value = initialAllowSet; } }, { diff --git a/toolkit/devtools/commandline/test/browser_gcli_remotews.js b/toolkit/devtools/commandline/test/browser_gcli_remotews.js index 7b9237e191..e4bb7085d8 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_remotews.js +++ b/toolkit/devtools/commandline/test/browser_gcli_remotews.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testRemoteWs.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_remotews.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); @@ -83,8 +68,8 @@ exports.testRemoteWebsocket = function(options) { check: { args: { prefix: { - value: function(connection) { - assert.is(connection.prefix, 'remote', 'disconnecting remote'); + value: function(front) { + assert.is(front.prefix, 'remote', 'disconnecting remote'); } } } @@ -112,8 +97,8 @@ exports.testRemoteWebsocket = function(options) { check: { args: { prefix: { - value: function(connection) { - assert.is(connection.prefix, 'remote', 'disconnecting remote'); + value: function(front) { + assert.is(front.prefix, 'remote', 'disconnecting remote'); } } } @@ -466,8 +451,8 @@ exports.testRemoteWebsocket = function(options) { unassigned: [ ], args: { prefix: { - value: function(connection) { - assert.is(connection.prefix, 'remote', 'disconnecting remote'); + value: function(front) { + assert.is(front.prefix, 'remote', 'disconnecting remote'); }, arg: ' remote', status: 'VALID', diff --git a/toolkit/devtools/commandline/test/browser_gcli_remotexhr.js b/toolkit/devtools/commandline/test/browser_gcli_remotexhr.js index b89b9d52b9..9b24ef6691 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_remotexhr.js +++ b/toolkit/devtools/commandline/test/browser_gcli_remotexhr.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testRemoteXhr.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_remotexhr.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); @@ -83,8 +68,8 @@ exports.testRemoteXhr = function(options) { check: { args: { prefix: { - value: function(connection) { - assert.is(connection.prefix, 'remote', 'disconnecting remote'); + value: function(front) { + assert.is(front.prefix, 'remote', 'disconnecting remote'); } } } @@ -112,8 +97,8 @@ exports.testRemoteXhr = function(options) { check: { args: { prefix: { - value: function(connection) { - assert.is(connection.prefix, 'remote', 'disconnecting remote'); + value: function(front) { + assert.is(front.prefix, 'remote', 'disconnecting remote'); } } } @@ -466,8 +451,8 @@ exports.testRemoteXhr = function(options) { unassigned: [ ], args: { prefix: { - value: function(connection) { - assert.is(connection.prefix, 'remote', 'disconnecting remote'); + value: function(front) { + assert.is(front.prefix, 'remote', 'disconnecting remote'); }, arg: ' remote', status: 'VALID', diff --git a/toolkit/devtools/commandline/test/browser_gcli_resource.js b/toolkit/devtools/commandline/test/browser_gcli_resource.js index 2a23253f75..3750190a3a 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_resource.js +++ b/toolkit/devtools/commandline/test/browser_gcli_resource.js @@ -15,31 +15,17 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testResource.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_resource.js"); } -// - +// var helpers = require('./helpers'); // var assert = require('../testharness/assert'); var Promise = require('gcli/util/promise').Promise; @@ -47,84 +33,85 @@ var util = require('gcli/util/util'); var resource = require('gcli/types/resource'); var Status = require('gcli/types/types').Status; - -var tempDocument; - -exports.setup = function(options) { - tempDocument = resource.getDocument(); - if (options.window) { - resource.setDocument(options.window.document); - } -}; - -exports.shutdown = function(options) { - resource.setDocument(tempDocument); - tempDocument = undefined; +exports.testCommand = function(options) { + return helpers.audit(options, [ + { + setup: 'tsres ', + check: { + predictionsContains: [ 'inline-css' ], + } + } + ]); }; exports.testAllPredictions1 = function(options) { - if (options.isFirefox || options.isNoDom) { - assert.log('Skipping checks due to firefox document.stylsheets support.'); + if (options.isRemote) { + assert.log('Can\'t directly test remote types locally.'); return; } + var context = options.requisition.conversionContext; var resource = options.requisition.system.types.createType('resource'); - return resource.getLookup().then(function(opts) { + return resource.getLookup(context).then(function(opts) { assert.ok(opts.length > 1, 'have all resources'); return util.promiseEach(opts, function(prediction) { - return checkPrediction(resource, prediction); + return checkPrediction(resource, prediction, context); }); }); }; exports.testScriptPredictions = function(options) { - if (options.isFirefox || options.isNoDom) { - assert.log('Skipping checks due to firefox document.stylsheets support.'); + if (options.isRemote || options.isNode) { + assert.log('Can\'t directly test remote types locally.'); return; } + var context = options.requisition.conversionContext; var types = options.requisition.system.types; var resource = types.createType({ name: 'resource', include: 'text/javascript' }); - return resource.getLookup().then(function(opts) { + return resource.getLookup(context).then(function(opts) { assert.ok(opts.length > 1, 'have js resources'); return util.promiseEach(opts, function(prediction) { - return checkPrediction(resource, prediction); + return checkPrediction(resource, prediction, context); }); }); }; exports.testStylePredictions = function(options) { - if (options.isFirefox || options.isNoDom) { - assert.log('Skipping checks due to firefox document.stylsheets support.'); + if (options.isRemote) { + assert.log('Can\'t directly test remote types locally.'); return; } + var context = options.requisition.conversionContext; var types = options.requisition.system.types; var resource = types.createType({ name: 'resource', include: 'text/css' }); - return resource.getLookup().then(function(opts) { + return resource.getLookup(context).then(function(opts) { assert.ok(opts.length >= 1, 'have css resources'); return util.promiseEach(opts, function(prediction) { - return checkPrediction(resource, prediction); + return checkPrediction(resource, prediction, context); }); }); }; exports.testAllPredictions2 = function(options) { - if (options.isNoDom) { - assert.log('Skipping checks due to nodom document.stylsheets support.'); + if (options.isRemote) { + assert.log('Can\'t directly test remote types locally.'); return; } + + var context = options.requisition.conversionContext; var types = options.requisition.system.types; var scriptRes = types.createType({ name: 'resource', include: 'text/javascript' }); - return scriptRes.getLookup().then(function(scriptOptions) { + return scriptRes.getLookup(context).then(function(scriptOptions) { var styleRes = types.createType({ name: 'resource', include: 'text/css' }); - return styleRes.getLookup().then(function(styleOptions) { + return styleRes.getLookup(context).then(function(styleOptions) { var allRes = types.createType({ name: 'resource' }); - return allRes.getLookup().then(function(allOptions) { + return allRes.getLookup(context).then(function(allOptions) { assert.is(scriptOptions.length + styleOptions.length, allOptions.length, 'split'); @@ -134,27 +121,26 @@ exports.testAllPredictions2 = function(options) { }; exports.testAllPredictions3 = function(options) { - if (options.isNoDom) { - assert.log('Skipping checks due to nodom document.stylsheets support.'); + if (options.isRemote) { + assert.log('Can\'t directly test remote types locally.'); return; } + var context = options.requisition.conversionContext; var types = options.requisition.system.types; var res1 = types.createType({ name: 'resource' }); - return res1.getLookup().then(function(options1) { + return res1.getLookup(context).then(function(options1) { var res2 = types.createType('resource'); - return res2.getLookup().then(function(options2) { + return res2.getLookup(context).then(function(options2) { assert.is(options1.length, options2.length, 'type spec'); }); }); }; -function checkPrediction(res, prediction) { +function checkPrediction(res, prediction, context) { var name = prediction.name; var value = prediction.value; - // resources don't need context so cheat and pass in null - var context = null; return res.parseString(name, context).then(function(conversion) { assert.is(conversion.getStatus(), Status.VALID, 'status VALID for ' + name); assert.is(conversion.value, value, 'value for ' + name); diff --git a/toolkit/devtools/commandline/test/browser_gcli_short.js b/toolkit/devtools/commandline/test/browser_gcli_short.js index 812d6ef5ed..17e30843de 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_short.js +++ b/toolkit/devtools/commandline/test/browser_gcli_short.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testShort.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_short.js"); } -// - // var helpers = require('./helpers'); exports.testBasic = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_spell.js b/toolkit/devtools/commandline/test/browser_gcli_spell.js index bcd130fee7..3138b91716 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_spell.js +++ b/toolkit/devtools/commandline/test/browser_gcli_spell.js @@ -14,31 +14,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testSpell.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_spell.js"); } -// - // var assert = require('../testharness/assert'); var spell = require('gcli/util/spell'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_split.js b/toolkit/devtools/commandline/test/browser_gcli_split.js index 5e32cbfb84..11fbbead9c 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_split.js +++ b/toolkit/devtools/commandline/test/browser_gcli_split.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testSplit.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_split.js"); } -// - // var assert = require('../testharness/assert'); var cli = require('gcli/cli'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_string.js b/toolkit/devtools/commandline/test/browser_gcli_string.js index 5f992dfdda..8470a0314e 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_string.js +++ b/toolkit/devtools/commandline/test/browser_gcli_string.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testString.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_string.js"); } -// - // var helpers = require('./helpers'); exports.testNewLine = function(options) { diff --git a/toolkit/devtools/commandline/test/browser_gcli_tokenize.js b/toolkit/devtools/commandline/test/browser_gcli_tokenize.js index dae64af84a..690ee3724c 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_tokenize.js +++ b/toolkit/devtools/commandline/test/browser_gcli_tokenize.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testTokenize.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_tokenize.js"); } -// - // var assert = require('../testharness/assert'); var cli = require('gcli/cli'); diff --git a/toolkit/devtools/commandline/test/browser_gcli_tooltip.js b/toolkit/devtools/commandline/test/browser_gcli_tooltip.js index 10aa558d75..73717acb9e 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_tooltip.js +++ b/toolkit/devtools/commandline/test/browser_gcli_tooltip.js @@ -15,40 +15,20 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testTooltip.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_tooltip.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); exports.testActivate = function(options) { - if (!options.display) { - assert.log('No display. Skipping activate tests'); - return; - } - return helpers.audit(options, [ { setup: ' ', diff --git a/toolkit/devtools/commandline/test/browser_gcli_types.js b/toolkit/devtools/commandline/test/browser_gcli_types.js index 01c11c39d6..3ec238d580 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_types.js +++ b/toolkit/devtools/commandline/test/browser_gcli_types.js @@ -15,49 +15,25 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testTypes.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_types.js"); } -// - // var assert = require('../testharness/assert'); var util = require('gcli/util/util'); var Promise = require('gcli/util/promise').Promise; -var nodetype = require('gcli/types/node'); -exports.setup = function(options) { - if (options.window) { - nodetype.setDocument(options.window.document); - } -}; - -exports.shutdown = function(options) { - nodetype.unsetDocument(); -}; - -function forEachType(options, typeSpec, callback) { +function forEachType(options, templateTypeSpec, callback) { var types = options.requisition.system.types; return util.promiseEach(types.getTypeNames(), function(name) { + var typeSpec = {}; + util.copyProperties(templateTypeSpec, typeSpec); typeSpec.name = name; typeSpec.requisition = options.requisition; @@ -79,29 +55,19 @@ function forEachType(options, typeSpec, callback) { else if (name === 'union') { typeSpec.alternatives = [{ name: 'string' }]; } + else if (options.isRemote) { + if (name === 'node' || name === 'nodelist') { + return; + } + } var type = types.createType(typeSpec); var reply = callback(type); - return Promise.resolve(reply).then(function(value) { - // Clean up - delete typeSpec.name; - delete typeSpec.requisition; - delete typeSpec.data; - delete typeSpec.delegateType; - delete typeSpec.subtype; - delete typeSpec.alternatives; - - return value; - }); + return Promise.resolve(reply); }); } exports.testDefault = function(options) { - if (options.isNoDom) { - assert.log('Skipping tests due to issues with resource type.'); - return; - } - return forEachType(options, {}, function(type) { var context = options.requisition.executionContext; var blank = type.getBlank(context).value; diff --git a/toolkit/devtools/commandline/test/browser_gcli_union.js b/toolkit/devtools/commandline/test/browser_gcli_union.js index 9f3dd08c13..0d688d16dd 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_union.js +++ b/toolkit/devtools/commandline/test/browser_gcli_union.js @@ -15,31 +15,16 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testUnion.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_union.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); @@ -126,7 +111,7 @@ exports.testDefault = function(options) { } }, { - skipIf: options.isPhantomjs, // Phantom goes weird with predictions + skipIf: options.isPhantomjs, // PhantomJS gets predictions wrong setup: 'unionc1 5', check: { input: 'unionc1 5', @@ -160,7 +145,7 @@ exports.testDefault = function(options) { } }, { - skipRemainingIf: options.isPhantomjs, + skipIf: options.isPhantomjs, // PhantomJS URL type is broken setup: 'unionc2 on', check: { input: 'unionc2 on', diff --git a/toolkit/devtools/commandline/test/browser_gcli_url.js b/toolkit/devtools/commandline/test/browser_gcli_url.js index 1fec41eb73..63baf05dd4 100644 --- a/toolkit/devtools/commandline/test/browser_gcli_url.js +++ b/toolkit/devtools/commandline/test/browser_gcli_url.js @@ -15,38 +15,23 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT -var exports = {}; - -var TEST_URI = "data:text/html;charset=utf-8,

gcli-testUrl.js

"; +const exports = {}; function test() { - return Task.spawn(function() { - let options = yield helpers.openTab(TEST_URI); - yield helpers.openToolbar(options); - gcli.addItems(mockCommands.items); - - yield helpers.runTests(options, exports); - - gcli.removeItems(mockCommands.items); - yield helpers.closeToolbar(options); - yield helpers.closeTab(options); - }).then(finish, helpers.handleError); + helpers.runTestModule(exports, "browser_gcli_url.js"); } -// - // var assert = require('../testharness/assert'); // var helpers = require('./helpers'); exports.testDefault = function(options) { return helpers.audit(options, [ { - skipRemainingIf: options.isPhantomjs, + skipRemainingIf: options.isPhantomjs, // PhantomJS URL type is broken setup: 'urlc', check: { input: 'urlc', diff --git a/toolkit/devtools/commandline/test/helpers.js b/toolkit/devtools/commandline/test/helpers.js index dc33b183b9..71c0be7a93 100644 --- a/toolkit/devtools/commandline/test/helpers.js +++ b/toolkit/devtools/commandline/test/helpers.js @@ -18,7 +18,7 @@ // A copy of this code exists in firefox mochitests. They should be kept // in sync. Hence the exports synonym for non AMD contexts. -var { helpers, gcli, assert } = (function() { +var { helpers, assert } = (function() { var helpers = {}; @@ -30,23 +30,24 @@ var util = require('gcli/util/util'); var Promise = require('gcli/util/promise').Promise; var cli = require('gcli/cli'); var KeyEvent = require('gcli/util/util').KeyEvent; -var gcli = require('gcli/index'); + +const { GcliFront } = require("devtools/server/actors/gcli"); /** * See notes in helpers.checkOptions() */ -var createFFDisplayAutomator = function(display) { +var createDeveloperToolbarAutomator = function(toolbar) { var automator = { setInput: function(typed) { - return display.inputter.setInput(typed); + return toolbar.inputter.setInput(typed); }, setCursor: function(cursor) { - return display.inputter.setCursor(cursor); + return toolbar.inputter.setCursor(cursor); }, focus: function() { - return display.inputter.focus(); + return toolbar.inputter.focus(); }, fakeKey: function(keyCode) { @@ -56,36 +57,36 @@ var createFFDisplayAutomator = function(display) { timeStamp: new Date().getTime() }; - display.inputter.onKeyDown(fakeEvent); + toolbar.inputter.onKeyDown(fakeEvent); if (keyCode === KeyEvent.DOM_VK_BACK_SPACE) { - var input = display.inputter.element; + var input = toolbar.inputter.element; input.value = input.value.slice(0, -1); } - return display.inputter.handleKeyUp(fakeEvent); + return toolbar.inputter.handleKeyUp(fakeEvent); }, getInputState: function() { - return display.inputter.getInputState(); + return toolbar.inputter.getInputState(); }, getCompleterTemplateData: function() { - return display.completer._getCompleterTemplateData(); + return toolbar.completer._getCompleterTemplateData(); }, getErrorMessage: function() { - return display.tooltip.errorEle.textContent; + return toolbar.tooltip.errorEle.textContent; } }; Object.defineProperty(automator, 'focusManager', { - get: function() { return display.focusManager; }, + get: function() { return toolbar.focusManager; }, enumerable: true }); Object.defineProperty(automator, 'field', { - get: function() { return display.tooltip.field; }, + get: function() { return toolbar.tooltip.field; }, enumerable: true }); @@ -223,9 +224,9 @@ helpers.openToolbar = function(options) { options.chromeWindow = options.chromeWindow || window; return options.chromeWindow.DeveloperToolbar.show(true).then(function() { - var display = options.chromeWindow.DeveloperToolbar.display; - options.automator = createFFDisplayAutomator(display); - options.requisition = display.requisition; + var toolbar = options.chromeWindow.DeveloperToolbar; + options.automator = createDeveloperToolbarAutomator(toolbar); + options.requisition = toolbar.requisition; return options; }); }; @@ -331,17 +332,17 @@ helpers.promiseify = function(functionWithLastParamCallback, scope) { * Warning: For use with Firefox Mochitests only. * * As addTab, but that also opens the developer toolbar. In addition a new - * 'automator' property is added to the options object with the display from GCLI - * in the developer toolbar + * 'automator' property is added to the options object which uses the + * developer toolbar */ helpers.addTabWithToolbar = function(url, callback, options) { return helpers.addTab(url, function(innerOptions) { var win = innerOptions.chromeWindow; return win.DeveloperToolbar.show(true).then(function() { - var display = win.DeveloperToolbar.display; - innerOptions.automator = createFFDisplayAutomator(display); - innerOptions.requisition = display.requisition; + var toolbar = win.DeveloperToolbar; + innerOptions.automator = createDeveloperToolbarAutomator(toolbar); + innerOptions.requisition = toolbar.requisition; var reply = callback.call(null, innerOptions); @@ -376,7 +377,7 @@ helpers.runTests = function(options, tests) { var recover = function(error) { ok(false, error); - console.error(error); + console.error(error, error.stack); }; info("SETUP"); @@ -410,6 +411,87 @@ helpers.runTests = function(options, tests) { }, recover); }; +const MOCK_COMMANDS_URI = "chrome://mochitests/content/browser/toolkit/devtools/commandline/test/mockCommands.js"; + +const defer = function() { + const deferred = { }; + deferred.promise = new Promise(function(resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + return deferred; +}; + +/** + * This does several actions associated with running a GCLI test in mochitest + * 1. Create a new tab containing basic markup for GCLI tests + * 2. Open the developer toolbar + * 3. Register the mock commands with the server process + * 4. Wait for the proxy commands to be auto-regitstered with the client + * 5. Register the mock converters with the client process + * 6. Run all the tests + * 7. Tear down all the setup + */ +helpers.runTestModule = function(exports, name) { + return Task.spawn(function*() { + const uri = "data:text/html;charset=utf-8," + + "" + + "
" + name + "
"; + + const options = yield helpers.openTab(uri); + options.isRemote = true; + + yield helpers.openToolbar(options); + + const system = options.requisition.system; + + // Register a one time listener with the local set of commands + const addedDeferred = defer(); + const removedDeferred = defer(); + let state = 'preAdd'; // Then 'postAdd' then 'postRemove' + + system.commands.onCommandsChange.add(function(ev) { + if (system.commands.get('tsslow') != null) { + if (state === 'preAdd') { + addedDeferred.resolve(); + state = 'postAdd'; + } + } + else { + if (state === 'postAdd') { + removedDeferred.resolve(); + state = 'postRemove'; + } + } + }); + + // Send a message to add the commands to the content process + const front = yield GcliFront.create(options.target); + yield front._testOnly_addItemsByModule(MOCK_COMMANDS_URI); + + // This will cause the local set of commands to be updated with the + // command proxies, wait for that to complete. + yield addedDeferred.promise; + + // Now we need to add the converters to the local GCLI + const converters = mockCommands.items.filter(item => item.item === 'converter'); + system.addItems(converters); + + // Next run the tests + yield helpers.runTests(options, exports); + + // Finally undo the mock commands and converters + system.removeItems(converters); + const removePromise = system.commands.onCommandsChange.once(); + yield front._testOnly_removeItemsByModule(MOCK_COMMANDS_URI); + yield removedDeferred.promise; + + // And close everything down + yield helpers.closeToolbar(options); + yield helpers.closeTab(options); + }).then(finish, helpers.handleError); +}; + /////////////////////////////////////////////////////////////////////////////// /** @@ -759,15 +841,15 @@ helpers._check = function(options, name, checks) { var outstanding = []; var suffix = name ? ' (for \'' + name + '\')' : ''; - if (!options.isNoDom && 'input' in checks) { + if (!options.isNode && 'input' in checks) { assert.is(helpers._actual.input(options), checks.input, 'input' + suffix); } - if (!options.isNoDom && 'cursor' in checks) { + if (!options.isNode && 'cursor' in checks) { assert.is(helpers._actual.cursor(options), checks.cursor, 'cursor' + suffix); } - if (!options.isNoDom && 'current' in checks) { + if (!options.isNode && 'current' in checks) { assert.is(helpers._actual.current(options), checks.current, 'current' + suffix); } @@ -775,18 +857,18 @@ helpers._check = function(options, name, checks) { assert.is(helpers._actual.status(options), checks.status, 'status' + suffix); } - if (!options.isNoDom && 'markup' in checks) { + if (!options.isNode && 'markup' in checks) { assert.is(helpers._actual.markup(options), checks.markup, 'markup' + suffix); } - if (!options.isNoDom && 'hints' in checks) { + if (!options.isNode && 'hints' in checks) { var hintCheck = function(actualHints) { assert.is(actualHints, checks.hints, 'hints' + suffix); }; outstanding.push(helpers._actual.hints(options).then(hintCheck)); } - if (!options.isNoDom && 'predictions' in checks) { + if (!options.isNode && 'predictions' in checks) { var predictionsCheck = function(actualPredictions) { helpers.arrayIs(actualPredictions, checks.predictions, @@ -795,12 +877,16 @@ helpers._check = function(options, name, checks) { outstanding.push(helpers._actual.predictions(options).then(predictionsCheck)); } - if (!options.isNoDom && 'predictionsContains' in checks) { + if (!options.isNode && 'predictionsContains' in checks) { var containsCheck = function(actualPredictions) { checks.predictionsContains.forEach(function(prediction) { var index = actualPredictions.indexOf(prediction); assert.ok(index !== -1, 'predictionsContains:' + prediction + suffix); + if (index === -1) { + log('Actual predictions (' + actualPredictions.length + '): ' + + actualPredictions.join(', ')); + } }); }; outstanding.push(helpers._actual.predictions(options).then(containsCheck)); @@ -813,26 +899,26 @@ helpers._check = function(options, name, checks) { } /* TODO: Fix this - if (!options.isNoDom && 'tooltipState' in checks) { + if (!options.isNode && 'tooltipState' in checks) { assert.is(helpers._actual.tooltipState(options), checks.tooltipState, 'tooltipState' + suffix); } */ - if (!options.isNoDom && 'outputState' in checks) { + if (!options.isNode && 'outputState' in checks) { assert.is(helpers._actual.outputState(options), checks.outputState, 'outputState' + suffix); } - if (!options.isNoDom && 'options' in checks) { + if (!options.isNode && 'options' in checks) { helpers.arrayIs(helpers._actual.options(options), checks.options, 'options' + suffix); } - if (!options.isNoDom && 'error' in checks) { + if (!options.isNode && 'error' in checks) { assert.is(helpers._actual.message(options), checks.error, 'error' + suffix); } @@ -894,7 +980,7 @@ helpers._check = function(options, name, checks) { 'arg.' + paramName + '.status' + suffix); } - if (!options.isNoDom && 'message' in check) { + if (!options.isNode && 'message' in check) { if (typeof check.message.test === 'function') { assert.ok(check.message.test(assignment.message), 'arg.' + paramName + '.message' + suffix); @@ -952,12 +1038,12 @@ helpers._exec = function(options, name, expected) { var context = requisition.conversionContext; var convertPromise; - if (options.isNoDom) { + if (options.isNode) { convertPromise = output.convert('string', context); } else { convertPromise = output.convert('dom', context).then(function(node) { - return node.textContent.trim(); + return (node == null) ? '' : node.textContent.trim(); }); } @@ -1171,9 +1257,8 @@ helpers.audit = function(options, audits) { ''; assert.log('Skipped ' + name + ' ' + skipReason); - // Tests need at least one pass, fail or todo. Let's create a dummy pass - // in case there are none. - ok(true, "Each test requires at least one pass, fail or todo so here is a pass."); + // Tests need at least one pass, fail or todo. Create a dummy pass + assert.ok(true, 'Each test requires at least one pass, fail or todo'); return Promise.resolve(undefined); } @@ -1270,5 +1355,5 @@ function log(message) { } } -return { helpers: helpers, gcli: gcli, assert: assert }; +return { helpers: helpers, assert: assert }; })(); diff --git a/toolkit/devtools/commandline/test/mockCommands.js b/toolkit/devtools/commandline/test/mockCommands.js index 0b9f9343f6..1a0d92df00 100644 --- a/toolkit/devtools/commandline/test/mockCommands.js +++ b/toolkit/devtools/commandline/test/mockCommands.js @@ -15,16 +15,21 @@ */ 'use strict'; -// // THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT -// DO NOT EDIT IT DIRECTLY - -// - +// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT var Promise = require('gcli/util/promise').Promise; -var mockCommands = {}; + +var mockCommands; +if (typeof exports !== 'undefined') { + // If we're being loaded via require(); + mockCommands = exports; +} +else { + // If we're being loaded via loadScript in mochitest + mockCommands = {}; +} // We use an alias for exports here because this module is used in Firefox // mochitests where we don't have define/require @@ -41,32 +46,70 @@ mockCommands.shutdown = function(requisition) { }; function createExec(name) { - return function(args, executionContext) { - var argsOut = Object.keys(args).map(function(key) { - return key + '=' + args[key]; - }).join(', '); - return 'Exec: ' + name + ' ' + argsOut; + return function(args, context) { + var promises = []; + + Object.keys(args).map(function(argName) { + var value = args[argName]; + var type = this.getParameterByName(argName).type; + var promise = Promise.resolve(type.stringify(value, context)); + promises.push(promise.then(function(str) { + return { name: argName, value: str }; + }.bind(this))); + }.bind(this)); + + return Promise.all(promises).then(function(data) { + var argValues = {}; + data.forEach(function(entry) { argValues[entry.name] = entry.value; }); + + return context.typedData('testCommandOutput', { + name: name, + args: argValues + }); + }.bind(this)); }; } mockCommands.items = [ { item: 'converter', - from: 'json', - to: 'string', - exec: function(json, context) { - return JSON.stringify(json, null, ' '); + from: 'testCommandOutput', + to: 'dom', + exec: function(testCommandOutput, context) { + var view = context.createView({ + data: testCommandOutput, + html: '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Exec: ${name}
${key}=${args[key]}
', + options: { + allowEval: true + } + }); + + return view.toDom(context.document); } }, { item: 'converter', - from: 'json', - to: 'view', - exec: function(json, context) { - var html = JSON.stringify(json, null, ' ').replace(/\n/g, '
'); - return { - html: '
' + html + '
' - }; + from: 'testCommandOutput', + to: 'string', + exec: function(testCommandOutput, context) { + var argsOut = Object.keys(testCommandOutput.args).map(function(key) { + return key + '=' + testCommandOutput.args[key]; + }).join(' '); + return 'Exec: ' + testCommandOutput.name + ' ' + argsOut; } }, { @@ -508,7 +551,7 @@ mockCommands.items = [ exec: function(args, context) { if (args.method === 'reject') { return new Promise(function(resolve, reject) { - setTimeout(function() { + context.environment.window.setTimeout(function() { reject('rejected promise'); }, 10); }); @@ -516,7 +559,7 @@ mockCommands.items = [ if (args.method === 'rejecttyped') { return new Promise(function(resolve, reject) { - setTimeout(function() { + context.environment.window.setTimeout(function() { reject(context.typedData('number', 54)); }, 10); }); @@ -524,7 +567,7 @@ mockCommands.items = [ if (args.method === 'throwinpromise') { return new Promise(function(resolve, reject) { - setTimeout(function() { + context.environment.window.setTimeout(function() { resolve('should be lost'); }, 10); }).then(function() { @@ -655,7 +698,7 @@ mockCommands.items = [ name: 'selection', data: function(context) { return new Promise(function(resolve, reject) { - setTimeout(function() { + context.environment.window.setTimeout(function() { resolve([ 'Shalom', 'Namasté', 'Hallo', 'Dydd-da', 'Chào', 'Hej', 'Saluton', 'Sawubona' @@ -738,5 +781,16 @@ mockCommands.items = [ exec: function(args, context) { return args; } + }, + { + item: 'command', + name: 'tsres', + params: [ + { + name: 'resource', + type: 'resource' + } + ], + exec: createExec('tsres'), } ]; diff --git a/toolkit/devtools/debugger/debugger-commands.js b/toolkit/devtools/debugger/debugger-commands.js index 1c17787a88..f7e375c4d0 100644 --- a/toolkit/devtools/debugger/debugger-commands.js +++ b/toolkit/devtools/debugger/debugger-commands.js @@ -5,7 +5,7 @@ "use strict"; const { Cc, Ci, Cu } = require("chrome"); -const gcli = require("gcli/index"); +const l10n = require("gcli/l10n"); loader.lazyImporter(this, "gDevTools", "resource://gre/modules/devtools/gDevTools.jsm"); @@ -67,8 +67,8 @@ function getAllSources(dbg) { */ exports.items.push({ name: "break", - description: gcli.lookup("breakDesc"), - manual: gcli.lookup("breakManual") + description: l10n.lookup("breakDesc"), + manual: l10n.lookup("breakManual") }); /** @@ -76,7 +76,9 @@ exports.items.push({ */ exports.items.push({ name: "break list", - description: gcli.lookup("breaklistDesc"), + item: "command", + runAt: "client", + description: l10n.lookup("breaklistDesc"), returnType: "breakpoints", exec: function(args, context) { let dbg = getPanel(context, "jsdebugger", { ensureOpened: true }); @@ -102,7 +104,7 @@ exports.items.push({ } else { return context.createView({ html: "

${message}

", - data: { message: gcli.lookup("breaklistNone") } + data: { message: l10n.lookup("breaklistNone") } }); } } @@ -126,7 +128,7 @@ var breakListHtml = "" + " data-command='break del ${breakpoint.label}'" + " onclick='${onclick}'" + " ondblclick='${ondblclick}'>" + - " " + gcli.lookup("breaklistOutRemove") + "" + + " " + l10n.lookup("breaklistOutRemove") + "" + " " + " " + " " + @@ -141,16 +143,18 @@ var MAX_LABEL_LENGTH = 20; */ exports.items.push({ name: "break add", - description: gcli.lookup("breakaddDesc"), - manual: gcli.lookup("breakaddManual") + description: l10n.lookup("breakaddDesc"), + manual: l10n.lookup("breakaddManual") }); /** * 'break add line' command */ exports.items.push({ + item: "command", + runAt: "client", name: "break add line", - description: gcli.lookup("breakaddlineDesc"), + description: l10n.lookup("breakaddlineDesc"), params: [ { name: "file", @@ -160,19 +164,19 @@ exports.items.push({ return getAllSources(getPanel(context, "jsdebugger")); } }, - description: gcli.lookup("breakaddlineFileDesc") + description: l10n.lookup("breakaddlineFileDesc") }, { name: "line", type: { name: "number", min: 1, step: 10 }, - description: gcli.lookup("breakaddlineLineDesc") + description: l10n.lookup("breakaddlineLineDesc") } ], returnType: "string", exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let deferred = context.defer(); @@ -182,9 +186,9 @@ exports.items.push({ let position = { actor: item.value, line: args.line }; dbg.addBreakpoint(position).then(() => { - deferred.resolve(gcli.lookup("breakaddAdded")); + deferred.resolve(l10n.lookup("breakaddAdded")); }, aError => { - deferred.resolve(gcli.lookupFormat("breakaddFailed", [aError])); + deferred.resolve(l10n.lookupFormat("breakaddFailed", [aError])); }); return deferred.promise; @@ -195,8 +199,10 @@ exports.items.push({ * 'break del' command */ exports.items.push({ + item: "command", + runAt: "client", name: "break del", - description: gcli.lookup("breakdelDesc"), + description: l10n.lookup("breakdelDesc"), params: [ { name: "breakpoint", @@ -214,14 +220,14 @@ exports.items.push({ })); } }, - description: gcli.lookup("breakdelBreakidDesc") + description: l10n.lookup("breakdelBreakidDesc") } ], returnType: "string", exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let source = dbg._view.Sources.getItemForAttachment(a => { @@ -233,9 +239,9 @@ exports.items.push({ line: args.breakpoint.lineNumber }; dbg.removeBreakpoint(position).then(() => { - deferred.resolve(gcli.lookup("breakdelRemoved")); + deferred.resolve(l10n.lookup("breakdelRemoved")); }, () => { - deferred.resolve(gcli.lookup("breakNotFound")); + deferred.resolve(l10n.lookup("breakNotFound")); }); return deferred.promise; @@ -247,16 +253,18 @@ exports.items.push({ */ exports.items.push({ name: "dbg", - description: gcli.lookup("dbgDesc"), - manual: gcli.lookup("dbgManual") + description: l10n.lookup("dbgDesc"), + manual: l10n.lookup("dbgManual") }); /** * 'dbg open' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg open", - description: gcli.lookup("dbgOpen"), + description: l10n.lookup("dbgOpen"), params: [], exec: function(args, context) { let target = context.environment.target; @@ -268,8 +276,10 @@ exports.items.push({ * 'dbg close' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg close", - description: gcli.lookup("dbgClose"), + description: l10n.lookup("dbgClose"), params: [], exec: function(args, context) { if (!getPanel(context, "jsdebugger")) { @@ -284,13 +294,15 @@ exports.items.push({ * 'dbg interrupt' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg interrupt", - description: gcli.lookup("dbgInterrupt"), + description: l10n.lookup("dbgInterrupt"), params: [], exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let controller = dbg._controller; @@ -305,13 +317,15 @@ exports.items.push({ * 'dbg continue' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg continue", - description: gcli.lookup("dbgContinue"), + description: l10n.lookup("dbgContinue"), params: [], exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let controller = dbg._controller; @@ -326,22 +340,26 @@ exports.items.push({ * 'dbg step' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg step", - description: gcli.lookup("dbgStepDesc"), - manual: gcli.lookup("dbgStepManual") + description: l10n.lookup("dbgStepDesc"), + manual: l10n.lookup("dbgStepManual") }); /** * 'dbg step over' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg step over", - description: gcli.lookup("dbgStepOverDesc"), + description: l10n.lookup("dbgStepOverDesc"), params: [], exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let controller = dbg._controller; @@ -356,13 +374,15 @@ exports.items.push({ * 'dbg step in' command */ exports.items.push({ + item: "command", + runAt: "client", name: 'dbg step in', - description: gcli.lookup("dbgStepInDesc"), + description: l10n.lookup("dbgStepInDesc"), params: [], exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let controller = dbg._controller; @@ -377,13 +397,15 @@ exports.items.push({ * 'dbg step over' command */ exports.items.push({ + item: "command", + runAt: "client", name: 'dbg step out', - description: gcli.lookup("dbgStepOutDesc"), + description: l10n.lookup("dbgStepOutDesc"), params: [], exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerStopped"); + return l10n.lookup("debuggerStopped"); } let controller = dbg._controller; @@ -398,14 +420,16 @@ exports.items.push({ * 'dbg list' command */ exports.items.push({ + item: "command", + runAt: "client", name: "dbg list", - description: gcli.lookup("dbgListSourcesDesc"), + description: l10n.lookup("dbgListSourcesDesc"), params: [], returnType: "dom", exec: function(args, context) { let dbg = getPanel(context, "jsdebugger"); if (!dbg) { - return gcli.lookup("debuggerClosed"); + return l10n.lookup("debuggerClosed"); } let sources = getAllSources(dbg); @@ -440,10 +464,12 @@ exports.items.push({ } ].forEach(function(cmd) { const lookup = function(id) { - return gcli.lookup(cmd.l10nPrefix + id); + return l10n.lookup(cmd.l10nPrefix + id); }; exports.items.push({ + item: "command", + runAt: "client", name: "dbg " + cmd.name, description: lookup("Desc"), params: [ @@ -475,7 +501,7 @@ exports.items.push({ const dbg = getPanel(context, "jsdebugger"); const doc = context.environment.chromeDocument; if (!dbg) { - throw new Error(gcli.lookup("debuggerClosed")); + throw new Error(l10n.lookup("debuggerClosed")); } const { promise, resolve, reject } = context.defer(); diff --git a/toolkit/devtools/eyedropper/commands.js b/toolkit/devtools/eyedropper/commands.js index 7b8ac20624..40b34cced3 100644 --- a/toolkit/devtools/eyedropper/commands.js +++ b/toolkit/devtools/eyedropper/commands.js @@ -2,7 +2,7 @@ * 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/. */ -const gcli = require("gcli/index"); +const l10n = require("gcli/l10n"); const EventEmitter = require("devtools/toolkit/event-emitter"); const eventEmitter = new EventEmitter(); @@ -12,14 +12,19 @@ let { Eyedropper, EyedropperManager } = require("devtools/eyedropper/eyedropper" * 'eyedropper' command */ exports.items = [{ + item: "command", + runAt: "client", name: "eyedropper", - description: gcli.lookup("eyedropperDesc"), - manual: gcli.lookup("eyedropperManual"), + description: l10n.lookup("eyedropperDesc"), + manual: l10n.lookup("eyedropperManual"), buttonId: "command-button-eyedropper", buttonClass: "command-button command-button-invertable", - tooltipText: gcli.lookup("eyedropperTooltip"), + tooltipText: l10n.lookup("eyedropperTooltip"), state: { isChecked: function(target) { + if (!target.tab) { + return false; + } let chromeWindow = target.tab.ownerDocument.defaultView; let dropper = EyedropperManager.getInstance(chromeWindow); if (dropper) { diff --git a/toolkit/devtools/framework/gDevTools.jsm b/toolkit/devtools/framework/gDevTools.jsm index 33e0105d9f..b3e4e70c19 100644 --- a/toolkit/devtools/framework/gDevTools.jsm +++ b/toolkit/devtools/framework/gDevTools.jsm @@ -808,6 +808,11 @@ let gDevToolsBrowser = { return !!(widgetWrapper && widgetWrapper.provider == CustomizableUI.PROVIDER_API); }, + /** + * The deferred promise will be resolved by WebIDE's UI.init() + */ + isWebIDEInitialized: promise.defer(), + /** * Uninstall WebIDE widget */ diff --git a/toolkit/devtools/framework/test/browser.ini b/toolkit/devtools/framework/test/browser.ini index 1d8a807c3e..17e40a0f7b 100644 --- a/toolkit/devtools/framework/test/browser.ini +++ b/toolkit/devtools/framework/test/browser.ini @@ -5,9 +5,11 @@ support-files = browser_toolbox_options_disable_js_iframe.html browser_toolbox_options_disable_cache.sjs browser_toolbox_sidebar_tool.xul + code_math.js head.js helper_disable_cache.js doc_theme.css + doc_viewsource.html browser_toolbox_options_enable_serviceworkers_testing.html serviceworker.js @@ -47,6 +49,10 @@ skip-if = e10s # Bug 1069044 - destroyInspector may hang during shutdown [browser_toolbox_tool_ready.js] [browser_toolbox_tool_remote_reopen.js] [browser_toolbox_transport_events.js] +[browser_toolbox_view_source_01.js] +[browser_toolbox_view_source_02.js] +[browser_toolbox_view_source_03.js] +[browser_toolbox_view_source_04.js] [browser_toolbox_window_reload_target.js] [browser_toolbox_window_shortcuts.js] skip-if = os == "mac" && os_version == "10.8" || os == "win" && os_version == "5.1" # Bug 851129 - Re-enable browser_toolbox_window_shortcuts.js test after leaks are fixed @@ -55,6 +61,6 @@ skip-if = os == "mac" && os_version == "10.8" || os == "win" && os_version == "5 [browser_toolbox_custom_host.js] [browser_toolbox_theme_registration.js] [browser_toolbox_options_enable_serviceworkers_testing.js] -skip-if = e10s # Bug 1030318 +skip-if = true # Bug 1153407 - this test breaks subsequent tests and is not e10s compatible diff --git a/toolkit/devtools/framework/test/browser_toolbox_tool_remote_reopen.js b/toolkit/devtools/framework/test/browser_toolbox_tool_remote_reopen.js index 76d7e4c296..85b3d75fae 100644 --- a/toolkit/devtools/framework/test/browser_toolbox_tool_remote_reopen.js +++ b/toolkit/devtools/framework/test/browser_toolbox_tool_remote_reopen.js @@ -118,6 +118,10 @@ function test() { todo(false, "Front for " + actor + " still held in pool!"); continue; } + // gcliActor is for the commandline which is separate to the toolbox + if (actor.contains("gcliActor")) { + continue; + } ok(false, "Front for " + actor + " still held in pool!"); } } diff --git a/toolkit/devtools/framework/test/browser_toolbox_view_source_01.js b/toolkit/devtools/framework/test/browser_toolbox_view_source_01.js new file mode 100644 index 0000000000..667f6f5797 --- /dev/null +++ b/toolkit/devtools/framework/test/browser_toolbox_view_source_01.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that Toolbox#viewSourceInDebugger works when debugger is not + * yet opened. + */ + +let URL = `${URL_ROOT}doc_viewsource.html`; +let JS_URL = `${URL_ROOT}code_math.js`; + +function *viewSource() { + let toolbox = yield loadToolbox(URL); + + yield toolbox.viewSourceInDebugger(JS_URL, 2); + + let debuggerPanel = toolbox.getPanel("jsdebugger"); + ok(debuggerPanel, "The debugger panel was opened."); + is(toolbox.currentToolId, "jsdebugger", "The debugger panel was selected."); + + let { DebuggerView } = debuggerPanel.panelWin; + let Sources = DebuggerView.Sources; + + is(Sources.selectedValue, getSourceActor(Sources, JS_URL), + "The correct source is shown in the debugger."); + is(DebuggerView.editor.getCursor().line + 1, 2, + "The correct line is highlighted in the debugger's source editor."); + + yield unloadToolbox(toolbox); + finish(); +} + +function test () { + Task.spawn(viewSource).then(finish, (aError) => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + finish(); + }); +} diff --git a/toolkit/devtools/framework/test/browser_toolbox_view_source_02.js b/toolkit/devtools/framework/test/browser_toolbox_view_source_02.js new file mode 100644 index 0000000000..e2779fc886 --- /dev/null +++ b/toolkit/devtools/framework/test/browser_toolbox_view_source_02.js @@ -0,0 +1,46 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that Toolbox#viewSourceInDebugger works when debugger is already loaded. + */ + +let URL = `${URL_ROOT}doc_viewsource.html`; +let JS_URL = `${URL_ROOT}code_math.js`; + +function *viewSource() { + let toolbox = yield loadToolbox(URL); + let { panelWin: debuggerWin } = yield toolbox.selectTool("jsdebugger"); + let debuggerEvents = debuggerWin.EVENTS; + let { DebuggerView } = debuggerWin; + let Sources = DebuggerView.Sources; + + yield debuggerWin.once(debuggerEvents.SOURCE_SHOWN); + ok("A source was shown in the debugger."); + + is(Sources.selectedValue, getSourceActor(Sources, JS_URL), + "The correct source is initially shown in the debugger."); + is(DebuggerView.editor.getCursor().line, 0, + "The correct line is initially highlighted in the debugger's source editor."); + + yield toolbox.viewSourceInDebugger(JS_URL, 2); + + let debuggerPanel = toolbox.getPanel("jsdebugger"); + ok(debuggerPanel, "The debugger panel was opened."); + is(toolbox.currentToolId, "jsdebugger", "The debugger panel was selected."); + + is(Sources.selectedValue, getSourceActor(Sources, JS_URL), + "The correct source is shown in the debugger."); + is(DebuggerView.editor.getCursor().line + 1, 2, + "The correct line is highlighted in the debugger's source editor."); + + yield unloadToolbox(toolbox); + finish(); +} + +function test () { + Task.spawn(viewSource).then(finish, (aError) => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + finish(); + }); +} diff --git a/toolkit/devtools/framework/test/browser_toolbox_view_source_03.js b/toolkit/devtools/framework/test/browser_toolbox_view_source_03.js new file mode 100644 index 0000000000..611f75aaaa --- /dev/null +++ b/toolkit/devtools/framework/test/browser_toolbox_view_source_03.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that Toolbox#viewSourceInStyleEditor works when style editor is not + * yet opened. + */ + +let URL = `${URL_ROOT}doc_viewsource.html`; +let CSS_URL = `${URL_ROOT}doc_theme.css`; + +function *viewSource() { + let toolbox = yield loadToolbox(URL); + + let fileFound = yield toolbox.viewSourceInStyleEditor(CSS_URL, 2); + ok(fileFound, "viewSourceInStyleEditor should resolve to true if source found."); + + let stylePanel = toolbox.getPanel("styleeditor"); + ok(stylePanel, "The style editor panel was opened."); + is(toolbox.currentToolId, "styleeditor", "The style editor panel was selected."); + + let { UI } = stylePanel; + + is(UI.selectedEditor.styleSheet.href, CSS_URL, + "The correct source is shown in the style editor."); + is(UI.selectedEditor.sourceEditor.getCursor().line + 1, 2, + "The correct line is highlighted in the style editor's source editor."); + + yield unloadToolbox(toolbox); + finish(); +} + +function test () { + Task.spawn(viewSource).then(finish, (aError) => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + finish(); + }); +} diff --git a/toolkit/devtools/framework/test/browser_toolbox_view_source_04.js b/toolkit/devtools/framework/test/browser_toolbox_view_source_04.js new file mode 100644 index 0000000000..aefab0b948 --- /dev/null +++ b/toolkit/devtools/framework/test/browser_toolbox_view_source_04.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that Toolbox#viewSourceInScratchpad works. + */ + +let URL = `${URL_ROOT}doc_viewsource.html`; + +function *viewSource() { + let toolbox = yield loadToolbox(URL); + let win = yield openScratchpadWindow(); + let { Scratchpad: scratchpad } = win; + + // Brahm's Cello Sonata No.1, Op.38 now in the scratchpad + scratchpad.setText("E G B C B\nA B A G A B\nG E"); + let scratchpadURL = scratchpad.uniqueName; + + // Now select another tool for focus + yield toolbox.selectTool("webconsole"); + + yield toolbox.viewSourceInScratchpad(scratchpadURL, 2); + + is(scratchpad.editor.getCursor().line, 2, + "The correct line is highlighted in scratchpad's editor."); + + win.close(); + yield unloadToolbox(toolbox); + finish(); +} + +function test () { + Task.spawn(viewSource).then(finish, (aError) => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + finish(); + }); +} diff --git a/toolkit/devtools/framework/test/code_math.js b/toolkit/devtools/framework/test/code_math.js new file mode 100644 index 0000000000..97c289411f --- /dev/null +++ b/toolkit/devtools/framework/test/code_math.js @@ -0,0 +1,4 @@ +function add(a, b, k) { + var result = a + b; + return k(result); +} diff --git a/toolkit/devtools/framework/test/doc_viewsource.html b/toolkit/devtools/framework/test/doc_viewsource.html new file mode 100644 index 0000000000..7094eb87eb --- /dev/null +++ b/toolkit/devtools/framework/test/doc_viewsource.html @@ -0,0 +1,13 @@ + + + + + Toolbox test for View Source methods + + + + + + + diff --git a/toolkit/devtools/framework/test/head.js b/toolkit/devtools/framework/test/head.js index fb65dd3e0f..c2ece1bd14 100644 --- a/toolkit/devtools/framework/test/head.js +++ b/toolkit/devtools/framework/test/head.js @@ -7,6 +7,7 @@ let TargetFactory = gDevTools.TargetFactory; const { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {}); const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {}); const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +const { ScratchpadManager } = Cu.import("resource:///modules/devtools/scratchpad-manager.jsm", {}); const URL_ROOT = "http://example.com/browser/browser/devtools/framework/test/"; const CHROME_URL_ROOT = "chrome://mochitests/content/browser/browser/devtools/framework/test/"; @@ -175,3 +176,49 @@ function getChromeActors(callback) DebuggerServer.destroy(); }); } + +function loadToolbox (url) { + let { promise: p, resolve } = promise.defer(); + gBrowser.selectedTab = gBrowser.addTab(); + let target = TargetFactory.forTab(gBrowser.selectedTab); + + gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) { + gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true); + gDevTools.showToolbox(target).then(resolve); + }, true); + + content.location = url; + return p; +} + +function unloadToolbox (toolbox) { + return toolbox.destroy().then(function() { + gBrowser.removeCurrentTab(); + }); +} + +function getSourceActor(aSources, aURL) { + let item = aSources.getItemForAttachment(a => a.source.url === aURL); + return item && item.value; +} + +/** + * Open a Scratchpad window. + * + * @return nsIDOMWindow + * The new window object that holds Scratchpad. + */ +function *openScratchpadWindow () { + let { promise: p, resolve } = promise.defer(); + let win = ScratchpadManager.openScratchpad(); + + yield once(win, "load"); + + win.Scratchpad.addObserver({ + onReady: function () { + win.Scratchpad.removeObserver(this); + resolve(win); + } + }); + return p; +} diff --git a/toolkit/devtools/framework/toolbox.js b/toolkit/devtools/framework/toolbox.js index fa47688d93..4e0f80e94a 100644 --- a/toolkit/devtools/framework/toolbox.js +++ b/toolkit/devtools/framework/toolbox.js @@ -21,6 +21,7 @@ let Telemetry = require("devtools/shared/telemetry"); let {getHighlighterUtils} = require("devtools/framework/toolbox-highlighter-utils"); let {HUDService} = require("devtools/webconsole/hudservice"); let {showDoorhanger} = require("devtools/shared/doorhanger"); +let sourceUtils = require("devtools/shared/source-utils"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -716,10 +717,13 @@ Toolbox.prototype = { this._buildPickerButton(); } - let spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec"); - let environment = CommandUtils.createEnvironment(this, '_target'); - return CommandUtils.createRequisition(environment).then(requisition => { + const options = { + environment: CommandUtils.createEnvironment(this, '_target') + }; + return CommandUtils.createRequisition(this.target, options).then(requisition => { this._requisition = requisition; + + const spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec"); return CommandUtils.createButtons(spec, this.target, this.doc, requisition).then(buttons => { let container = this.doc.getElementById("toolbox-buttons"); @@ -1704,6 +1708,7 @@ Toolbox.prototype = { gDevTools.off("pref-changed", this._prefChanged); this._lastFocusedElement = null; + if (this.webconsolePanel) { this._saveSplitConsoleHeight(); this.webconsolePanel.removeEventListener("resize", @@ -1751,7 +1756,7 @@ Toolbox.prototype = { let win = this.frame.ownerGlobal; if (this._requisition) { - this._requisition.destroy(); + CommandUtils.destroyRequisition(this._requisition, this.target); } this._telemetry.toolClosed("toolbox"); this._telemetry.destroy(); @@ -1873,4 +1878,48 @@ Toolbox.prototype = { yield this._performanceConnection.destroy(); this._performanceConnection = null; }), + + /** + * Returns gViewSourceUtils for viewing source. + */ + get gViewSourceUtils() { + return this.frame.contentWindow.gViewSourceUtils; + }, + + /** + * Opens source in style editor. Falls back to plain "view-source:". + * @see browser/devtools/shared/source-utils.js + */ + viewSourceInStyleEditor: function (sourceURL, sourceLine) { + return sourceUtils.viewSourceInStyleEditor(this, sourceURL, sourceLine); + }, + + /** + * Opens source in debugger. Falls back to plain "view-source:". + * @see browser/devtools/shared/source-utils.js + */ + viewSourceInDebugger: function (sourceURL, sourceLine) { + return sourceUtils.viewSourceInDebugger(this, sourceURL, sourceLine); + }, + + /** + * Opens source in scratchpad. Falls back to plain "view-source:". + * TODO The `sourceURL` for scratchpad instances are like `Scratchpad/1`. + * If instances are scoped one-per-browser-window, then we should be able + * to infer the URL from this toolbox, or use the built in scratchpad IN + * the toolbox. + * + * @see browser/devtools/shared/source-utils.js + */ + viewSourceInScratchpad: function (sourceURL, sourceLine) { + return sourceUtils.viewSourceInScratchpad(sourceURL, sourceLine); + }, + + /** + * Opens source in plain "view-source:". + * @see browser/devtools/shared/source-utils.js + */ + viewSource: function (sourceURL, sourceLine) { + return sourceUtils.viewSource(this, sourceURL, sourceLine); + }, }; diff --git a/toolkit/devtools/framework/toolbox.xul b/toolkit/devtools/framework/toolbox.xul index ad2f42b5d2..8aa5348284 100644 --- a/toolkit/devtools/framework/toolbox.xul +++ b/toolkit/devtools/framework/toolbox.xul @@ -15,6 +15,9 @@ + + + +
+
+
+ +
+ + diff --git a/toolkit/devtools/shared/widgets/filter-widget.css b/toolkit/devtools/shared/widgets/filter-widget.css new file mode 100644 index 0000000000..66edf832d2 --- /dev/null +++ b/toolkit/devtools/shared/widgets/filter-widget.css @@ -0,0 +1,122 @@ +/* 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/. */ + +#container { + color: var(--theme-body-color); + padding: 5px; + font: message-box; +} + +#container.dragging { + -moz-user-select: none; +} + +.theme-light #add-filter, +.theme-light .remove-button { + filter: invert(1); +} + +.filter { + display: flex; + margin-bottom: 10px; +} + +.filter-name, +.filter-value { + display: flex; + align-items: center; +} + +.filter-name { + padding-right: 10px; + flex: 1; +} + +.filter-value { + min-width: 150px; + flex: 2; +} + +.remove-button { + width: 16px; + height: 16px; + background: url(chrome://browser/skin/devtools/close@2x.png); + background-size: 16px; + font-size: 0; + border: none; + cursor: pointer; +} + +/* drag/drop handle */ +#container i { + width: 10px; + margin-right: 15px; + padding: 10px 0; + cursor: grab; +} + +#container i::before { + content: ''; + display: block; + width: 10px; + height: 1px; + background: currentColor; + box-shadow: 0 3px 0 0 currentColor, + 0 -3px 0 0 currentColor; +} + +#container .dragging { + position: relative; + z-index: 1; + cursor: grab; +} + +.filter-name label { + -moz-user-select: none; + flex-grow: 1; +} + +.filter-name label.devtools-draglabel { + cursor: ew-resize; +} + +.filter-value input { + min-width: 50%; + flex-grow: 1; +} + +.filter-value span { + max-width: 20px; + width: 20px; +} + +/* message shown when there's no filter specified */ +#container p { + text-align: center; + line-height: 20px; +} + +#editor-footer { + display: flex; + justify-content: flex-end; +} + +#editor-footer select { + flex-grow: 1; + box-sizing: border-box; + font: inherit; + margin: 0 3px; +} + +#add-filter { + -moz-appearance: none; + background: url(chrome://browser/skin/devtools/add.svg); + background-size: 18px; + border: none; + width: 16px; + height: 16px; + font-size: 0; + vertical-align: middle; + cursor: pointer; +} diff --git a/toolkit/devtools/styleeditor/styleeditor-commands.js b/toolkit/devtools/styleeditor/styleeditor-commands.js index dd151627f2..5a61c70efc 100644 --- a/toolkit/devtools/styleeditor/styleeditor-commands.js +++ b/toolkit/devtools/styleeditor/styleeditor-commands.js @@ -4,12 +4,30 @@ "use strict"; -const gcli = require("gcli/index"); +const l10n = require("gcli/l10n"); +/** + * The `edit` command opens the toolbox to the style editor, with a given + * stylesheet open. + * + * This command is tricky. The 'edit' command uses the toolbox, so it's + * clearly runAt:client, but it uses the 'resource' type which accesses the + * DOM, so it must also be runAt:server. + * + * Our solution is to have the command technically be runAt:server, but to not + * actually do anything other than basically `return args;`, and have the + * converter (all converters are runAt:client) do the actual work of opening + * a toolbox. + * + * For alternative solutions that we considered, see the comment on commit + * 2645af7. + */ exports.items = [{ + item: "command", + runAt: "server", name: "edit", - description: gcli.lookup("editDesc"), - manual: gcli.lookup("editManual2"), + description: l10n.lookup("editDesc"), + manual: l10n.lookup("editManual2"), params: [ { name: 'resource', @@ -17,7 +35,7 @@ exports.items = [{ name: 'resource', include: 'text/css' }, - description: gcli.lookup("editResourceDesc") + description: l10n.lookup("editResourceDesc") }, { name: "line", @@ -27,15 +45,23 @@ exports.items = [{ min: 1, step: 10 }, - description: gcli.lookup("editLineToJumpToDesc") + description: l10n.lookup("editLineToJumpToDesc") } ], + returnType: "editArgs", + exec: args => { + return { href: args.resource.name, line: args.line }; + } +}, { + item: "converter", + from: "editArgs", + to: "dom", exec: function(args, context) { let target = context.environment.target; let gDevTools = require("resource://gre/modules/devtools/gDevTools.jsm").gDevTools; return gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) { let styleEditor = toolbox.getCurrentPanel(); - styleEditor.selectStyleSheet(args.resource.element, args.line); + styleEditor.selectStyleSheet(args.href, args.line); return null; }); } diff --git a/toolkit/devtools/styleeditor/test/browser_styleeditor_cmd_edit.js b/toolkit/devtools/styleeditor/test/browser_styleeditor_cmd_edit.js index ffd8fdc06b..f27a20b8a3 100644 --- a/toolkit/devtools/styleeditor/test/browser_styleeditor_cmd_edit.js +++ b/toolkit/devtools/styleeditor/test/browser_styleeditor_cmd_edit.js @@ -180,14 +180,6 @@ function spawnTest() { setup: "edit css#style2", check: { input: "edit css#style2", - args: { - resource: { - value: function(resource) { - let style2 = options.window.document.getElementById("style2"); - return resource.element.ownerNode == style2; - } - } - } }, exec: { output: "" } }, diff --git a/toolkit/devtools/styleinspector/computed-view.js b/toolkit/devtools/styleinspector/computed-view.js index 580df946c9..9e2c80bc94 100644 --- a/toolkit/devtools/styleinspector/computed-view.js +++ b/toolkit/devtools/styleinspector/computed-view.js @@ -1515,8 +1515,8 @@ SelectorView.prototype = { contentDoc = rawNode.ownerDocument; } } - let viewSourceUtils = inspector.viewSourceUtils; - viewSourceUtils.viewSource(rule.href, null, contentDoc, rule.line); + let toolbox = gDevTools.getToolbox(inspector.target); + toolbox.viewSource(rule.href, rule.line); return; } diff --git a/toolkit/devtools/styleinspector/rule-view.js b/toolkit/devtools/styleinspector/rule-view.js index db3cd67f39..aa277fe89a 100644 --- a/toolkit/devtools/styleinspector/rule-view.js +++ b/toolkit/devtools/styleinspector/rule-view.js @@ -2703,15 +2703,19 @@ TextPropertyEditor.prototype = { this.element.removeAttribute("dirty"); } - let colorSwatchClass = "ruleview-colorswatch"; - let bezierSwatchClass = "ruleview-bezierswatch"; + const sharedSwatchClass = "ruleview-swatch "; + const colorSwatchClass = "ruleview-colorswatch"; + const bezierSwatchClass = "ruleview-bezierswatch"; + const filterSwatchClass = "ruleview-filterswatch"; let outputParser = this.ruleEditor.ruleView._outputParser; let frag = outputParser.parseCssProperty(name, val, { - colorSwatchClass: colorSwatchClass, + colorSwatchClass: sharedSwatchClass + colorSwatchClass, colorClass: "ruleview-color", - bezierSwatchClass: bezierSwatchClass, + bezierSwatchClass: sharedSwatchClass + bezierSwatchClass, bezierClass: "ruleview-bezier", + filterSwatchClass: sharedSwatchClass + filterSwatchClass, + filterClass: "ruleview-filter", defaultColorType: !propDirty, urlClass: "theme-link", baseURI: this.sheetURI @@ -2749,6 +2753,20 @@ TextPropertyEditor.prototype = { } } + // Attach the filter editor tooltip to the filter swatch + let span = this.valueSpan.querySelector("." + filterSwatchClass); + if (this.ruleEditor.isEditable) { + if(span) { + let originalValue = this.valueSpan.textContent; + + this.ruleEditor.ruleView.tooltips.filterEditor.addSwatch(span, { + onPreview: () => this._previewValue(this.valueSpan.textContent), + onCommit: () => this._applyNewValue(this.valueSpan.textContent), + onRevert: () => this._applyNewValue(originalValue, false) + }); + } + } + // Populate the computed styles. this._updateComputed(); }, diff --git a/toolkit/devtools/styleinspector/style-inspector-overlays.js b/toolkit/devtools/styleinspector/style-inspector-overlays.js index 6b38ae8cfe..35dbab8eed 100644 --- a/toolkit/devtools/styleinspector/style-inspector-overlays.js +++ b/toolkit/devtools/styleinspector/style-inspector-overlays.js @@ -16,7 +16,8 @@ const {Cc, Ci, Cu} = require("chrome"); const { Tooltip, SwatchColorPickerTooltip, - SwatchCubicBezierTooltip + SwatchCubicBezierTooltip, + SwatchFilterTooltip } = require("devtools/shared/widgets/Tooltip"); const {CssLogic} = require("devtools/styleinspector/css-logic"); const {Promise:promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); @@ -255,7 +256,8 @@ TooltipsOverlay.prototype = { get isEditing() { return this.colorPicker.tooltip.isShown() || this.colorPicker.eyedropperOpen || - this.cubicBezier.tooltip.isShown(); + this.cubicBezier.tooltip.isShown() || + this.filterEditor.tooltip.isShown(); }, /** @@ -277,6 +279,8 @@ TooltipsOverlay.prototype = { this.colorPicker = new SwatchColorPickerTooltip(this.view.inspector.panelDoc); // Cubic bezier tooltip this.cubicBezier = new SwatchCubicBezierTooltip(this.view.inspector.panelDoc); + // Filter editor tooltip + this.filterEditor = new SwatchFilterTooltip(this.view.inspector.panelDoc); } this._isStarted = true; @@ -302,6 +306,10 @@ TooltipsOverlay.prototype = { this.cubicBezier.destroy(); } + if (this.filterEditor) { + this.filterEditor.destroy(); + } + this._isStarted = false; }, @@ -342,13 +350,13 @@ TooltipsOverlay.prototype = { let nodeInfo = this.view.getNodeInfo(target); if (!nodeInfo) { // The hovered node isn't something we care about - return promise.reject(); + return promise.reject(false); } let type = this._getTooltipType(nodeInfo); if (!type) { // There is no tooltip type defined for the hovered node - return promise.reject(); + return promise.reject(false); } if (this.isRuleView && this.colorPicker.tooltip.isShown()) { @@ -361,6 +369,11 @@ TooltipsOverlay.prototype = { this.cubicBezier.hide(); } + if (this.isRuleView && this.filterEditor.tooltip.isShown()) { + this.filterEditor.revert(); + this.filterEdtior.hide(); + } + let inspector = this.view.inspector; if (type === TOOLTIP_IMAGE_TYPE) { @@ -389,6 +402,10 @@ TooltipsOverlay.prototype = { if (this.cubicBezier) { this.cubicBezier.hide(); } + + if (this.filterEditor) { + this.filterEditor.hide(); + } }, /** diff --git a/toolkit/devtools/styleinspector/style-inspector.js b/toolkit/devtools/styleinspector/style-inspector.js index b2a7f2672c..6996ba4c21 100644 --- a/toolkit/devtools/styleinspector/style-inspector.js +++ b/toolkit/devtools/styleinspector/style-inspector.js @@ -111,9 +111,9 @@ RuleViewTool.prototype = { // these sheets in the view source window instead. if (!sheet || sheet.isSystem) { let contentDoc = this.inspector.selection.document; - let viewSourceUtils = this.inspector.viewSourceUtils; let href = rule.nodeHref || rule.href; - viewSourceUtils.viewSource(href, null, contentDoc, rule.line || 0); + let toolbox = gDevTools.getToolbox(this.inspector.target); + toolbox.viewSource(href, rule.line); return; } diff --git a/toolkit/devtools/tilt/tilt-commands.js b/toolkit/devtools/tilt/tilt-commands.js index 384293c5a9..613ec9e566 100644 --- a/toolkit/devtools/tilt/tilt-commands.js +++ b/toolkit/devtools/tilt/tilt-commands.js @@ -4,7 +4,7 @@ "use strict"; -const gcli = require("gcli/index"); +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. @@ -19,18 +19,18 @@ Object.defineProperty(this, "TiltManager", { exports.items = [ { name: 'tilt', - description: gcli.lookup("tiltDesc"), - manual: gcli.lookup("tiltManual"), + description: l10n.lookup("tiltDesc"), + manual: l10n.lookup("tiltManual"), hidden: true }, { name: 'tilt open', - description: gcli.lookup("tiltOpenDesc"), - manual: gcli.lookup("tiltOpenManual"), + description: l10n.lookup("tiltOpenDesc"), + manual: l10n.lookup("tiltOpenManual"), hidden: true, exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; @@ -44,7 +44,7 @@ exports.items = [ name: "tilt toggle", buttonId: "command-button-tilt", buttonClass: "command-button command-button-invertable", - tooltipText: gcli.lookup("tiltToggleTooltip"), + tooltipText: l10n.lookup("tiltToggleTooltip"), hidden: true, state: { isChecked: function(aTarget) { @@ -73,7 +73,7 @@ exports.items = [ }, exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; @@ -83,28 +83,28 @@ exports.items = [ }, { name: 'tilt translate', - description: gcli.lookup("tiltTranslateDesc"), - manual: gcli.lookup("tiltTranslateManual"), + description: l10n.lookup("tiltTranslateDesc"), + manual: l10n.lookup("tiltTranslateManual"), hidden: true, params: [ { name: "x", type: "number", defaultValue: 0, - description: gcli.lookup("tiltTranslateXDesc"), - manual: gcli.lookup("tiltTranslateXManual") + description: l10n.lookup("tiltTranslateXDesc"), + manual: l10n.lookup("tiltTranslateXManual") }, { name: "y", type: "number", defaultValue: 0, - description: gcli.lookup("tiltTranslateYDesc"), - manual: gcli.lookup("tiltTranslateYManual") + description: l10n.lookup("tiltTranslateYDesc"), + manual: l10n.lookup("tiltTranslateYManual") } ], exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; @@ -116,35 +116,35 @@ exports.items = [ }, { name: 'tilt rotate', - description: gcli.lookup("tiltRotateDesc"), - manual: gcli.lookup("tiltRotateManual"), + 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: gcli.lookup("tiltRotateXDesc"), - manual: gcli.lookup("tiltRotateXManual") + description: l10n.lookup("tiltRotateXDesc"), + manual: l10n.lookup("tiltRotateXManual") }, { name: "y", type: { name: 'number', min: -360, max: 360, step: 10 }, defaultValue: 0, - description: gcli.lookup("tiltRotateYDesc"), - manual: gcli.lookup("tiltRotateYManual") + description: l10n.lookup("tiltRotateYDesc"), + manual: l10n.lookup("tiltRotateYManual") }, { name: "z", type: { name: 'number', min: -360, max: 360, step: 10 }, defaultValue: 0, - description: gcli.lookup("tiltRotateZDesc"), - manual: gcli.lookup("tiltRotateZManual") + description: l10n.lookup("tiltRotateZDesc"), + manual: l10n.lookup("tiltRotateZManual") } ], exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; @@ -156,20 +156,20 @@ exports.items = [ }, { name: 'tilt zoom', - description: gcli.lookup("tiltZoomDesc"), - manual: gcli.lookup("tiltZoomManual"), + description: l10n.lookup("tiltZoomDesc"), + manual: l10n.lookup("tiltZoomManual"), hidden: true, params: [ { name: "zoom", type: { name: 'number' }, - description: gcli.lookup("tiltZoomAmountDesc"), - manual: gcli.lookup("tiltZoomAmountManual") + description: l10n.lookup("tiltZoomAmountDesc"), + manual: l10n.lookup("tiltZoomAmountManual") } ], exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; @@ -182,12 +182,12 @@ exports.items = [ }, { name: 'tilt reset', - description: gcli.lookup("tiltResetDesc"), - manual: gcli.lookup("tiltResetManual"), + description: l10n.lookup("tiltResetDesc"), + manual: l10n.lookup("tiltResetManual"), hidden: true, exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; @@ -200,12 +200,12 @@ exports.items = [ }, { name: 'tilt close', - description: gcli.lookup("tiltCloseDesc"), - manual: gcli.lookup("tiltCloseManual"), + description: l10n.lookup("tiltCloseDesc"), + manual: l10n.lookup("tiltCloseManual"), hidden: true, exec: function(args, context) { if (isMultiProcess(context)) { - return gcli.lookupFormat("notAvailableInE10S", [this.name]); + return l10n.lookupFormat("notAvailableInE10S", [this.name]); } let chromeWindow = context.environment.chromeDocument.defaultView; diff --git a/toolkit/devtools/webconsole/console-commands.js b/toolkit/devtools/webconsole/console-commands.js index 6033cb80b9..15fa6b85d9 100644 --- a/toolkit/devtools/webconsole/console-commands.js +++ b/toolkit/devtools/webconsole/console-commands.js @@ -4,16 +4,18 @@ "use strict"; -const gcli = require("gcli/index"); -const { gDevTools } = require("resource://gre/modules/devtools/gDevTools.jsm"); +const l10n = require("gcli/l10n"); +loader.lazyGetter(this, "gDevTools", () => require("resource://gre/modules/devtools/gDevTools.jsm").gDevTools); exports.items = [ { + item: "command", + runAt: "client", name: 'splitconsole', hidden: true, buttonId: "command-button-splitconsole", buttonClass: "command-button command-button-invertable", - tooltipText: gcli.lookup("splitconsoleTooltip"), + tooltipText: l10n.lookup("splitconsoleTooltip"), isRemoteSafe: true, state: { isChecked: function(target) { @@ -50,12 +52,14 @@ exports.items = [ }, { name: "console", - description: gcli.lookup("consoleDesc"), - manual: gcli.lookup("consoleManual") + description: l10n.lookup("consoleDesc"), + manual: l10n.lookup("consoleManual") }, { + item: "command", + runAt: "client", name: "console clear", - description: gcli.lookup("consoleclearDesc"), + description: l10n.lookup("consoleclearDesc"), exec: function(args, context) { let toolbox = gDevTools.getToolbox(context.environment.target); if (toolbox == null) { @@ -71,19 +75,24 @@ exports.items = [ } }, { + item: "command", + runAt: "client", name: "console close", - description: gcli.lookup("consolecloseDesc"), + description: l10n.lookup("consolecloseDesc"), exec: function(args, context) { - // Don't return a value to GCLI - return gDevTools.closeToolbox(context.environment.target).then(() => {}); + return gDevTools.closeToolbox(context.environment.target) + .then(() => {}); // Don't return a value to GCLI } }, { + item: "command", + runAt: "client", name: "console open", - description: gcli.lookup("consoleopenDesc"), + description: l10n.lookup("consoleopenDesc"), exec: function(args, context) { - // Don't return a value to GCLI - return gDevTools.showToolbox(context.environment.target, "webconsole").then(() => {}); + const target = context.environment.target; + return gDevTools.showToolbox(target, "webconsole") + .then(() => {}); // Don't return a value to GCLI } } ]; diff --git a/toolkit/devtools/webconsole/console-output.js b/toolkit/devtools/webconsole/console-output.js index 71e9ab5ed5..f9243f9433 100644 --- a/toolkit/devtools/webconsole/console-output.js +++ b/toolkit/devtools/webconsole/console-output.js @@ -7,6 +7,8 @@ const {Cc, Ci, Cu} = require("chrome"); +const { Services } = require("resource://gre/modules/Services.jsm"); + loader.lazyImporter(this, "VariablesView", "resource://gre/modules/devtools/VariablesView.jsm"); loader.lazyImporter(this, "escapeHTML", "resource://gre/modules/devtools/VariablesView.jsm"); loader.lazyImporter(this, "gDevTools", "resource://gre/modules/devtools/gDevTools.jsm"); diff --git a/toolkit/devtools/webconsole/hudservice.js b/toolkit/devtools/webconsole/hudservice.js index 315221daa9..2f5ca77ed8 100644 --- a/toolkit/devtools/webconsole/hudservice.js +++ b/toolkit/devtools/webconsole/hudservice.js @@ -19,6 +19,7 @@ loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm"); loader.lazyImporter(this, "DebuggerServer", "resource://gre/modules/devtools/dbg-server.jsm"); loader.lazyImporter(this, "DebuggerClient", "resource://gre/modules/devtools/dbg-client.jsm"); loader.lazyGetter(this, "showDoorhanger", () => require("devtools/shared/doorhanger").showDoorhanger); +loader.lazyRequireGetter(this, "sourceUtils", "devtools/shared/source-utils"); const STRINGS_URI = "chrome://global/locale/devtools/webconsole.properties"; let l10n = new WebConsoleUtils.l10n(STRINGS_URI); @@ -448,10 +449,8 @@ WebConsole.prototype = { * @param integer aSourceLine * The line number which should be highlighted. */ - viewSource: function WC_viewSource(aSourceURL, aSourceLine) - { - this.gViewSourceUtils.viewSource(aSourceURL, null, - this.iframeWindow.document, aSourceLine); + viewSource: function WC_viewSource(aSourceURL, aSourceLine) { + this.gViewSourceUtils.viewSource(aSourceURL, null, this.iframeWindow.document, aSourceLine || 0); }, /** @@ -459,30 +458,20 @@ WebConsole.prototype = { * instance in the Style Editor. If the file is not found, it is opened in * source view instead. * + * Manually handle the case where toolbox does not exist (Browser Console). + * * @param string aSourceURL * The URL of the file. * @param integer aSourceLine * The line number which you want to place the caret. - * TODO: This function breaks the client-server boundaries. - * To be fixed in bug 793259. */ - viewSourceInStyleEditor: - function WC_viewSourceInStyleEditor(aSourceURL, aSourceLine) - { + viewSourceInStyleEditor: function WC_viewSourceInStyleEditor(aSourceURL, aSourceLine) { let toolbox = gDevTools.getToolbox(this.target); if (!toolbox) { this.viewSource(aSourceURL, aSourceLine); return; } - - gDevTools.showToolbox(this.target, "styleeditor").then(function(toolbox) { - try { - toolbox.getCurrentPanel().selectStyleSheet(aSourceURL, aSourceLine); - } catch(e) { - // Open view source if style editor fails. - this.viewSource(aSourceURL, aSourceLine); - } - }); + toolbox.viewSourceInStyleEditor(aSourceURL, aSourceLine); }, /** @@ -490,49 +479,24 @@ WebConsole.prototype = { * instance in the Script Debugger. If the file is not found, it is opened in * source view instead. * + * Manually handle the case where toolbox does not exist (Browser Console). + * * @param string aSourceURL * The URL of the file. * @param integer aSourceLine * The line number which you want to place the caret. */ - viewSourceInDebugger: - function WC_viewSourceInDebugger(aSourceURL, aSourceLine) - { + viewSourceInDebugger: function WC_viewSourceInDebugger(aSourceURL, aSourceLine) { let toolbox = gDevTools.getToolbox(this.target); if (!toolbox) { this.viewSource(aSourceURL, aSourceLine); return; } - - let showSource = ({ DebuggerView }) => { - let item = DebuggerView.Sources.getItemForAttachment( - a => a.source.url === aSourceURL - ); - if (item) { - DebuggerView.setEditorLocation(item.attachment.source.actor, aSourceLine, - { noDebug: true }).then(() => { - this.ui.emit("source-in-debugger-opened"); - }); - return; - } - toolbox.selectTool("webconsole") - .then(() => this.viewSource(aSourceURL, aSourceLine)); - } - - // If the Debugger was already open, switch to it and try to show the - // source immediately. Otherwise, initialize it and wait for the sources - // to be added first. - let debuggerAlreadyOpen = toolbox.getPanel("jsdebugger"); - toolbox.selectTool("jsdebugger").then(({ panelWin: dbg }) => { - if (debuggerAlreadyOpen) { - showSource(dbg); - } else { - dbg.once(dbg.EVENTS.SOURCES_ADDED, () => showSource(dbg)); - } - }); + toolbox.viewSourceInDebugger(aSourceURL, aSourceLine).then(() => { + this.ui.emit("source-in-debugger-opened"); + }) }, - /** * Tries to open a JavaScript file related to the web page for the web console * instance in the corresponding Scratchpad. @@ -540,33 +504,8 @@ WebConsole.prototype = { * @param string aSourceURL * The URL of the file which corresponds to a Scratchpad id. */ - viewSourceInScratchpad: function WC_viewSourceInScratchpad(aSourceURL) - { - // Check for matching top level Scratchpad window. - let wins = Services.wm.getEnumerator("devtools:scratchpad"); - - while (wins.hasMoreElements()) { - let win = wins.getNext(); - - if (!win.closed && win.Scratchpad.uniqueName === aSourceURL) { - win.focus(); - return; - } - } - - // Check for matching Scratchpad toolbox tab. - for (let [, toolbox] of gDevTools) { - let scratchpadPanel = toolbox.getPanel("scratchpad"); - if (scratchpadPanel) { - let { scratchpad } = scratchpadPanel; - if (scratchpad.uniqueName === aSourceURL) { - toolbox.selectTool("scratchpad"); - toolbox.raise(); - scratchpad.editor.focus(); - return; - } - } - } + viewSourceInScratchpad: function WC_viewSourceInScratchpad(aSourceURL, aSourceLine) { + sourceUtils.viewSourceInScratchpad(aSourceURL, aSourceLine); }, /** diff --git a/toolkit/devtools/webconsole/webconsole.js b/toolkit/devtools/webconsole/webconsole.js index 3f0d39a4a7..4bcdfbe25e 100644 --- a/toolkit/devtools/webconsole/webconsole.js +++ b/toolkit/devtools/webconsole/webconsole.js @@ -2703,7 +2703,7 @@ WebConsoleFrame.prototype = { let onClick = () => { let target = locationNode.target; if (target == "scratchpad" || isScratchpad) { - this.owner.viewSourceInScratchpad(url); + this.owner.viewSourceInScratchpad(url, line); return; } diff --git a/toolkit/devtools/webide/content/devicepreferences.js b/toolkit/devtools/webide/content/devicepreferences.js index 26228a93a6..db1f6103b1 100644 --- a/toolkit/devtools/webide/content/devicepreferences.js +++ b/toolkit/devtools/webide/content/devicepreferences.js @@ -33,7 +33,7 @@ function CloseUI() { } function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "list-tabs-response") { + if (what == "connection" || what == "runtime-global-actors") { BuildUI(); } } diff --git a/toolkit/devtools/webide/content/devicesettings.js b/toolkit/devtools/webide/content/devicesettings.js index dc8867b8ca..d0813b9eb3 100644 --- a/toolkit/devtools/webide/content/devicesettings.js +++ b/toolkit/devtools/webide/content/devicesettings.js @@ -33,7 +33,7 @@ function CloseUI() { } function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "list-tabs-response") { + if (what == "connection" || what == "runtime-global-actors") { BuildUI(); } } diff --git a/toolkit/devtools/webide/content/jar.mn b/toolkit/devtools/webide/content/jar.mn index 2f7c45eeb3..a178df8cf6 100644 --- a/toolkit/devtools/webide/content/jar.mn +++ b/toolkit/devtools/webide/content/jar.mn @@ -28,3 +28,8 @@ webide.jar: content/wifi-auth.xhtml (wifi-auth.xhtml) content/logs.xhtml (logs.xhtml) content/logs.js (logs.js) + content/project-listing.xhtml (project-listing.xhtml) + content/project-listing.js (project-listing.js) + content/project-panel.js (project-panel.js) + content/simulator.js (simulator.js) + content/simulator.xhtml (simulator.xhtml) diff --git a/toolkit/devtools/webide/content/monitor.js b/toolkit/devtools/webide/content/monitor.js index 6268dfc241..c2b551c1cc 100644 --- a/toolkit/devtools/webide/content/monitor.js +++ b/toolkit/devtools/webide/content/monitor.js @@ -116,7 +116,7 @@ let Monitor = { */ onAppManagerUpdate: function(event, what, details) { switch (what) { - case 'list-tabs-response': + case 'runtime-global-actors': Monitor.connectToRuntime(); break; case 'connection': diff --git a/toolkit/devtools/webide/content/newapp.js b/toolkit/devtools/webide/content/newapp.js index 31ab8802ee..726c3048f4 100644 --- a/toolkit/devtools/webide/content/newapp.js +++ b/toolkit/devtools/webide/content/newapp.js @@ -15,9 +15,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Dow const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm"); const {AppProjects} = require("devtools/app-manager/app-projects"); -const APP_CREATOR_LIST = "devtools.webide.templatesURL"; const {AppManager} = require("devtools/webide/app-manager"); -const {GetTemplatesJSON} = require("devtools/webide/remote-resources"); +const {getJSON} = require("devtools/shared/getjson"); + +const TEMPLATES_URL = "devtools.webide.templatesURL"; let gTemplateList = null; @@ -30,11 +31,11 @@ window.addEventListener("load", function onLoad() { window.removeEventListener("load", onLoad); let projectNameNode = document.querySelector("#project-name"); projectNameNode.addEventListener("input", canValidate, true); - getJSON(); + getTemplatesJSON(); }, true); -function getJSON() { - GetTemplatesJSON().then(list => { +function getTemplatesJSON() { + getJSON(TEMPLATES_URL).then(list => { if (!Array.isArray(list)) { throw new Error("JSON response not an array"); } diff --git a/toolkit/devtools/webide/content/permissionstable.js b/toolkit/devtools/webide/content/permissionstable.js index 73e9b27f74..f71d241086 100644 --- a/toolkit/devtools/webide/content/permissionstable.js +++ b/toolkit/devtools/webide/content/permissionstable.js @@ -25,7 +25,7 @@ function CloseUI() { } function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "list-tabs-response") { + if (what == "connection" || what == "runtime-global-actors") { BuildUI(); } } diff --git a/toolkit/devtools/webide/content/project-listing.js b/toolkit/devtools/webide/content/project-listing.js new file mode 100644 index 0000000000..5f5372abb6 --- /dev/null +++ b/toolkit/devtools/webide/content/project-listing.js @@ -0,0 +1,49 @@ +/* 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/. */ + +const Cu = Components.utils; +const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; +const {AppManager} = require("devtools/webide/app-manager"); +const ProjectList = require("devtools/webide/project-list"); + +let projectList = new ProjectList(window, window.parent); + +window.addEventListener("load", function onLoad() { + window.removeEventListener("load", onLoad); + AppManager.on("app-manager-update", onAppManagerUpdate); + document.getElementById("new-app").onclick = CreateNewApp; + document.getElementById("hosted-app").onclick = ImportHostedApp; + document.getElementById("packaged-app").onclick = ImportPackagedApp; + projectList.update(); +}, true); + +window.addEventListener("unload", function onUnload() { + window.removeEventListener("unload", onUnload); + projectList = null; + AppManager.off("app-manager-update", onAppManagerUpdate); +}); + +function onAppManagerUpdate(event, what, details) { + switch (what) { + case "runtime-global-actors": + case "runtime-targets": + case "project-validated": + case "project-removed": + case "project": + projectList.update(details); + break; + } +} + +function CreateNewApp() { + projectList.newApp(); +} + +function ImportHostedApp() { + projectList.importHostedApp(); +} + +function ImportPackagedApp() { + projectList.importPackagedApp(); +} diff --git a/toolkit/devtools/webide/content/project-listing.xhtml b/toolkit/devtools/webide/content/project-listing.xhtml new file mode 100644 index 0000000000..2d11b89102 --- /dev/null +++ b/toolkit/devtools/webide/content/project-listing.xhtml @@ -0,0 +1,33 @@ + + + + + + %webideDTD; +]> + + + + + + + + +
+
+ + + + +
+ +
+ +
+
+
+ + diff --git a/toolkit/devtools/webide/content/project-panel.js b/toolkit/devtools/webide/content/project-panel.js new file mode 100644 index 0000000000..544bd6f2f7 --- /dev/null +++ b/toolkit/devtools/webide/content/project-panel.js @@ -0,0 +1,39 @@ +/* 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/. */ + +let ProjectPanel = { + // TODO: Expand function to save toggle state. + toggle: function(sidebarsEnabled, triggerPopup) { + let deferred = promise.defer(); + let doc = document; + + if (sidebarsEnabled) { + doc.querySelector("#project-listing-panel").setAttribute("sidebar-displayed", true); + doc.querySelector("#project-listing-splitter").setAttribute("sidebar-displayed", true); + deferred.resolve(); + } else if (triggerPopup) { + let panelNode = doc.querySelector("#project-panel"); + let panelVboxNode = doc.querySelector("#project-panel > #project-panel-box"); + let anchorNode = doc.querySelector("#project-panel-button > .panel-button-anchor"); + + window.setTimeout(() => { + // Open the popup only when the projects are added. + // Not doing it in the next tick can cause mis-calculations + // of the size of the panel. + function onPopupShown() { + panelNode.removeEventListener("popupshown", onPopupShown); + deferred.resolve(); + } + + panelNode.addEventListener("popupshown", onPopupShown); + panelNode.openPopup(anchorNode); + panelVboxNode.scrollTop = 0; + }, 0); + } else { + deferred.resolve(); + } + + return deferred.promise; + } +}; diff --git a/toolkit/devtools/webide/content/runtimedetails.js b/toolkit/devtools/webide/content/runtimedetails.js index 80baea324b..58f80fcc90 100644 --- a/toolkit/devtools/webide/content/runtimedetails.js +++ b/toolkit/devtools/webide/content/runtimedetails.js @@ -35,7 +35,7 @@ function CloseUI() { } function OnAppManagerUpdate(event, what) { - if (what == "connection" || what == "list-tabs-response") { + if (what == "connection" || what == "runtime-global-actors") { BuildUI(); CheckLockState(); } diff --git a/toolkit/devtools/webide/content/simulator.js b/toolkit/devtools/webide/content/simulator.js new file mode 100644 index 0000000000..c53c03d56c --- /dev/null +++ b/toolkit/devtools/webide/content/simulator.js @@ -0,0 +1,320 @@ +/* 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/. */ + +const Cu = Components.utils; + +const { require } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; +const { GetDevices, GetDeviceString } = require("devtools/shared/devices"); +const { Services } = Cu.import("resource://gre/modules/Services.jsm"); +const { Simulators, Simulator } = require("devtools/webide/simulators"); +const EventEmitter = require('devtools/toolkit/event-emitter'); +const promise = require("promise"); +const utils = require("devtools/webide/utils"); + +const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties"); + +let SimulatorEditor = { + + // Available Firefox OS Simulator addons (key: `addon.id`). + _addons: {}, + + // Available device simulation profiles (key: `device.name`). + _devices: {}, + + // The names of supported simulation options. + _deviceOptions: [], + + // The
element used to edit Simulator options. + _form: null, + + // The Simulator object being edited. + _simulator: null, + + // Generate the dynamic form elements. + init() { + let promises = []; + + // Grab the element. + let form = this._form; + if (!form) { + // This is the first time we run `init()`, bootstrap some things. + form = this._form = document.querySelector("#simulator-editor"); + form.addEventListener("change", this.update.bind(this)); + Simulators.on("configure", (e, simulator) => { this.edit(simulator) }); + // Extract the list of device simulation options we'll support. + let deviceFields = form.querySelectorAll("*[data-device]"); + this._deviceOptions = [].map.call(deviceFields, field => field.name); + } + + // Append a new
+ + + diff --git a/toolkit/devtools/webide/content/webide.js b/toolkit/devtools/webide/content/webide.js index c9dc9bee3f..ef2da12069 100644 --- a/toolkit/devtools/webide/content/webide.js +++ b/toolkit/devtools/webide/content/webide.js @@ -19,10 +19,13 @@ const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); const ProjectEditor = require("projecteditor/projecteditor"); const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm"); const {GetAvailableAddons} = require("devtools/webide/addons"); -const {GetTemplatesJSON, GetAddonsJSON} = require("devtools/webide/remote-resources"); +const {getJSON} = require("devtools/shared/getjson"); const utils = require("devtools/webide/utils"); +const Telemetry = require("devtools/shared/telemetry"); const {RuntimeScanners, WiFiScanner} = require("devtools/webide/runtimes"); const {showDoorhanger} = require("devtools/shared/doorhanger"); +const ProjectList = require("devtools/webide/project-list"); +const {Simulators} = require("devtools/webide/simulators"); const Strings = Services.strings.createBundle("chrome://global/locale/devtools/webide.properties"); @@ -32,8 +35,10 @@ const HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Troubleshootin const MAX_ZOOM = 1.4; const MIN_ZOOM = 0.6; -// download template index early -GetTemplatesJSON(true); +// Download remote resources early +getJSON("devtools.webide.addonsURL", true); +getJSON("devtools.webide.templatesURL", true); +getJSON("devtools.devices.url", true); // See bug 989619 console.log = console.log.bind(console); @@ -47,11 +52,16 @@ window.addEventListener("load", function onLoad() { window.addEventListener("unload", function onUnload() { window.removeEventListener("unload", onUnload); - UI.uninit(); + UI.destroy(); }); +let projectList; + let UI = { init: function() { + this._telemetry = new Telemetry(); + this._telemetry.toolOpened("webide"); + AppManager.init(); this.onMessage = this.onMessage.bind(this); @@ -60,6 +70,9 @@ let UI = { this.appManagerUpdate = this.appManagerUpdate.bind(this); AppManager.on("app-manager-update", this.appManagerUpdate); + projectList = new ProjectList(window, window); + ProjectPanel.toggle(projectList.sidebarsEnabled); + this.updateCommands(); this.updateRuntimeList(); @@ -68,6 +81,7 @@ let UI = { AppProjects.load().then(() => { this.autoSelectProject(); + projectList.update(); }, e => { console.error(e); this.reportError("error_appProjectsLoadFailed"); @@ -103,14 +117,22 @@ let UI = { .QueryInterface(Ci.nsIDocShell) .contentViewer; this.contentViewer.fullZoom = Services.prefs.getCharPref("devtools.webide.zoom"); + + gDevToolsBrowser.isWebIDEInitialized.resolve(); + + this.configureSimulator = this.configureSimulator.bind(this); + Simulators.on("configure", this.configureSimulator); }, - uninit: function() { + destroy: function() { window.removeEventListener("focus", this.onfocus, true); AppManager.off("app-manager-update", this.appManagerUpdate); - AppManager.uninit(); + AppManager.destroy(); + Simulators.off("configure", this.configureSimulator); + projectList = null; window.removeEventListener("message", this.onMessage); this.updateConnectionTelemetry(); + this._telemetry.toolClosed("webide"); }, canCloseProject: function() { @@ -140,8 +162,9 @@ let UI = { appManagerUpdate: function(event, what, details) { // Got a message from app-manager.js + // See AppManager.update() for descriptions of what these events mean. switch (what) { - case "runtimelist": + case "runtime-list": this.updateRuntimeList(); this.autoConnectRuntime(); break; @@ -164,17 +187,19 @@ let UI = { UI.openProject(); UI.autoStartProject(); UI.saveLastSelectedProject(); + projectList.update(); }); return; - case "project-is-not-running": - case "project-is-running": - case "list-tabs-response": + case "project-stopped": + case "project-started": + case "runtime-global-actors": this.updateCommands(); + projectList.update(); break; case "runtime-details": this.updateRuntimeButton(); break; - case "runtime-changed": + case "runtime": this.updateRuntimeButton(); this.saveLastConnectedRuntime(); break; @@ -183,12 +208,17 @@ let UI = { this.updateCommands(); this.updateProjectButton(); this.updateProjectEditorHeader(); + projectList.update(); + break; + case "project-removed": + projectList.update(); break; case "install-progress": this.updateProgress(Math.round(100 * details.bytesSent / details.totalBytes)); break; - case "runtime-apps-found": + case "runtime-targets": this.autoSelectProject(); + projectList.update(details); break; case "pre-package": this.prePackageLog(details); @@ -197,6 +227,10 @@ let UI = { this._updatePromise = promise.resolve(); }, + configureSimulator: function(event, simulator) { + UI.selectDeckPanel("simulator"); + }, + openInBrowser: function(url) { // Open a URL in a Firefox window let browserWin = Services.wm.getMostRecentWindow("navigator:browser"); @@ -218,10 +252,12 @@ let UI = { } }, + // TODO: remove hidePanel when project layout is complete - Bug 1079347 hidePanels: function() { let panels = document.querySelectorAll("panel"); for (let p of panels) { - p.hidePopup(); + // Sometimes in tests, p.hidePopup is not defined - Bug 1151796. + p.hidePopup && p.hidePopup(); } }, @@ -278,9 +314,8 @@ let UI = { }, busyUntil: function(promise, operationDescription) { - // Freeze the UI until the promise is resolved. A 30s timeout - // will unfreeze the UI, just in case the promise never gets - // resolved. + // Freeze the UI until the promise is resolved. A timeout will unfreeze the + // UI, just in case the promise never gets resolved. this._busyPromise = promise; this._busyOperationDescription = operationDescription; this.setupBusyTimeout(); @@ -445,7 +480,13 @@ let UI = { // |busyUntil| will listen for rejections. // Bug 1121100 may find a better way to silence these. }); - return this.busyUntil(promise, "Connecting to " + name); + promise = this.busyUntil(promise, "Connecting to " + name); + // Stop busy timeout for runtimes that take unknown or long amounts of time + // to connect. + if (runtime.prolongedConnection) { + this.cancelBusyTimeout(); + } + return promise; }, updateRuntimeButton: function() { @@ -510,14 +551,16 @@ let UI = { let project = AppManager.selectedProject; - if (!project) { - buttonNode.classList.add("no-project"); - labelNode.setAttribute("value", Strings.GetStringFromName("projectButton_label")); - imageNode.removeAttribute("src"); - } else { - buttonNode.classList.remove("no-project"); - labelNode.setAttribute("value", project.name); - imageNode.setAttribute("src", project.icon); + if (!projectList.sidebarsEnabled) { + if (!project) { + buttonNode.classList.add("no-project"); + labelNode.setAttribute("value", Strings.GetStringFromName("projectButton_label")); + imageNode.removeAttribute("src"); + } else { + buttonNode.classList.remove("no-project"); + labelNode.setAttribute("value", project.name); + imageNode.setAttribute("src", project.icon); + } } }, @@ -910,8 +953,10 @@ let UI = { // We can't know for sure which one was used here, so reset the // |toolboxPromise| since someone must be destroying it to reach here, // and call our own close method. - this.toolboxPromise = null; - this._closeToolboxUI(); + if (this.toolboxIframe && this.toolboxIframe.uid == json.uid) { + this.toolboxPromise = null; + this._closeToolboxUI(); + } break; } } catch(e) { console.error(e); } @@ -949,9 +994,13 @@ let UI = { let iframe = document.createElement("iframe"); iframe.id = "toolbox"; + // Compute a uid on the iframe in order to identify toolbox iframe + // when receiving toolbox-close event + iframe.uid = new Date().getTime(); + document.querySelector("notificationbox").insertBefore(iframe, splitter.nextSibling); let host = devtools.Toolbox.HostType.CUSTOM; - let options = { customIframe: iframe, zoom: false }; + let options = { customIframe: iframe, zoom: false, uid: iframe.uid }; this.toolboxIframe = iframe; let height = Services.prefs.getIntPref("devtools.toolbox.footer.height"); @@ -1016,211 +1065,31 @@ let Cmds = { * } */ newApp: function(testOptions) { - return UI.busyUntil(Task.spawn(function* () { - - // Open newapp.xul, which will feed ret.location - let ret = {location: null, testOptions: testOptions}; - window.openDialog("chrome://webide/content/newapp.xul", "newapp", "chrome,modal", ret); - if (!ret.location) - return; - - // Retrieve added project - let project = AppProjects.get(ret.location); - - // Select project - AppManager.selectedProject = project; - - }), "creating new app"); + projectList.newApp(testOptions); }, importPackagedApp: function(location) { - return UI.busyUntil(Task.spawn(function* () { - - let directory = utils.getPackagedDirectory(window, location); - - if (!directory) { - // User cancelled directory selection - return; - } - - yield UI.importAndSelectApp(directory); - }), "importing packaged app"); + projectList.importPackagedApp(location); }, importHostedApp: function(location) { - return UI.busyUntil(Task.spawn(function* () { - - let url = utils.getHostedURL(window, location); - - if (!url) { - return; - } - - yield UI.importAndSelectApp(url); - }), "importing hosted app"); + projectList.importHostedApp(location); }, showProjectPanel: function() { - let deferred = promise.defer(); + ProjectPanel.toggle(projectList.sidebarsEnabled, true); - let panelNode = document.querySelector("#project-panel"); - let panelVboxNode = document.querySelector("#project-panel > vbox"); - let anchorNode = document.querySelector("#project-panel-button > .panel-button-anchor"); - let projectsNode = document.querySelector("#project-panel-projects"); - - while (projectsNode.hasChildNodes()) { - projectsNode.firstChild.remove(); - } - - AppProjects.load().then(() => { - let projects = AppProjects.store.object.projects; - for (let i = 0; i < projects.length; i++) { - let project = projects[i]; - let panelItemNode = document.createElement("toolbarbutton"); - panelItemNode.className = "panel-item"; - projectsNode.appendChild(panelItemNode); - panelItemNode.setAttribute("label", project.name || AppManager.DEFAULT_PROJECT_NAME); - panelItemNode.setAttribute("image", project.icon || AppManager.DEFAULT_PROJECT_ICON); - if (!project.name || !project.icon) { - // The result of the validation process (storing names, icons, …) is not stored in - // the IndexedDB database when App Manager v1 is used. - // We need to run the validation again and update the name and icon of the app. - AppManager.validateAndUpdateProject(project).then(() => { - panelItemNode.setAttribute("label", project.name); - panelItemNode.setAttribute("image", project.icon); - }); - } - panelItemNode.addEventListener("click", () => { - UI.hidePanels(); - AppManager.selectedProject = project; - }, true); - } - - window.setTimeout(() => { - // Open the popup only when the projects are added. - // Not doing it in the next tick can cause mis-calculations - // of the size of the panel. - function onPopupShown() { - panelNode.removeEventListener("popupshown", onPopupShown); - deferred.resolve(); - } - panelNode.addEventListener("popupshown", onPopupShown); - panelNode.openPopup(anchorNode); - panelVboxNode.scrollTop = 0; - }, 0); - }, deferred.reject); - - - let runtimeappsHeaderNode = document.querySelector("#panel-header-runtimeapps"); - let sortedApps = []; - for (let [manifestURL, app] of AppManager.apps) { - sortedApps.push(app); - } - sortedApps = sortedApps.sort((a, b) => { - return a.manifest.name > b.manifest.name; - }); - let mainProcess = AppManager.isMainProcessDebuggable(); - if (AppManager.connected && (sortedApps.length > 0 || mainProcess)) { - runtimeappsHeaderNode.removeAttribute("hidden"); - } else { - runtimeappsHeaderNode.setAttribute("hidden", "true"); - } - - let runtimeAppsNode = document.querySelector("#project-panel-runtimeapps"); - while (runtimeAppsNode.hasChildNodes()) { - runtimeAppsNode.firstChild.remove(); - } - - if (mainProcess) { - let panelItemNode = document.createElement("toolbarbutton"); - panelItemNode.className = "panel-item"; - panelItemNode.setAttribute("label", Strings.GetStringFromName("mainProcess_label")); - panelItemNode.setAttribute("image", AppManager.DEFAULT_PROJECT_ICON); - runtimeAppsNode.appendChild(panelItemNode); - panelItemNode.addEventListener("click", () => { - UI.hidePanels(); - AppManager.selectedProject = { - type: "mainProcess", - name: Strings.GetStringFromName("mainProcess_label"), - icon: AppManager.DEFAULT_PROJECT_ICON - }; - }, true); - } - - for (let i = 0; i < sortedApps.length; i++) { - let app = sortedApps[i]; - let panelItemNode = document.createElement("toolbarbutton"); - panelItemNode.className = "panel-item"; - panelItemNode.setAttribute("label", app.manifest.name); - panelItemNode.setAttribute("image", app.iconURL); - runtimeAppsNode.appendChild(panelItemNode); - panelItemNode.addEventListener("click", () => { - UI.hidePanels(); - AppManager.selectedProject = { - type: "runtimeApp", - app: app.manifest, - icon: app.iconURL, - name: app.manifest.name - }; - }, true); - } - - // Build the tab list right now, so it's fast... - this._buildProjectPanelTabs(); - - // But re-list them and rebuild, in case any tabs navigated since the last - // time they were listed. - if (AppManager.connected) { - AppManager.listTabs().then(() => { - this._buildProjectPanelTabs(); + // There are currently no available events to listen for when an unselected + // tab navigates. Since we show every tab's location in the project menu, + // we re-list all the tabs each time the menu is displayed. + // TODO: An event-based solution will be needed for the sidebar UI. + if (!projectList.sidebarsEnabled && AppManager.connected) { + return AppManager.listTabs().then(() => { + projectList.updateTabs(); }).catch(console.error); } - return deferred.promise; - }, - - _buildProjectPanelTabs: function() { - let tabs = AppManager.tabStore.tabs; - let tabsHeaderNode = document.querySelector("#panel-header-tabs"); - if (AppManager.connected && tabs.length > 0) { - tabsHeaderNode.removeAttribute("hidden"); - } else { - tabsHeaderNode.setAttribute("hidden", "true"); - } - - let tabsNode = document.querySelector("#project-panel-tabs"); - while (tabsNode.hasChildNodes()) { - tabsNode.firstChild.remove(); - } - - for (let i = 0; i < tabs.length; i++) { - let tab = tabs[i]; - let url = new URL(tab.url); - // Wanted to use nsIFaviconService here, but it only works for visited - // tabs, so that's no help for any remote tabs. Maybe some favicon wizard - // knows how to get high-res favicons easily, or we could offer actor - // support for this (bug 1061654). - tab.favicon = url.origin + "/favicon.ico"; - tab.name = tab.title || Strings.GetStringFromName("project_tab_loading"); - if (url.protocol.startsWith("http")) { - tab.name = url.hostname + ": " + tab.name; - } - let panelItemNode = document.createElement("toolbarbutton"); - panelItemNode.className = "panel-item"; - panelItemNode.setAttribute("label", tab.name); - panelItemNode.setAttribute("image", tab.favicon); - tabsNode.appendChild(panelItemNode); - panelItemNode.addEventListener("click", () => { - UI.hidePanels(); - AppManager.selectedProject = { - type: "tab", - app: tab, - icon: tab.favicon, - location: tab.url, - name: tab.name - }; - }, true); - } + return promise.resolve(); }, showRuntimePanel: function() { @@ -1317,7 +1186,7 @@ let Cmds = { }, removeProject: function() { - return AppManager.removeSelectedProject(); + AppManager.removeSelectedProject(); }, toggleEditors: function() { diff --git a/toolkit/devtools/webide/content/webide.xul b/toolkit/devtools/webide/content/webide.xul index ba4ed38314..635bad8b58 100644 --- a/toolkit/devtools/webide/content/webide.xul +++ b/toolkit/devtools/webide/content/webide.xul @@ -12,6 +12,7 @@ + + @@ -150,7 +152,7 @@ - + @@ -191,21 +193,29 @@ - -