index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const { createSystem, connectFront, disconnectFront } = require("gcli/system");
  6. const { GcliFront } = require("devtools/shared/fronts/gcli");
  7. /**
  8. * This is the basic list of modules that should be loaded into each
  9. * requisition instance whether server side or client side
  10. */
  11. exports.baseModules = [
  12. "gcli/types/delegate",
  13. "gcli/types/selection",
  14. "gcli/types/array",
  15. "gcli/types/boolean",
  16. "gcli/types/command",
  17. "gcli/types/date",
  18. "gcli/types/file",
  19. "gcli/types/javascript",
  20. "gcli/types/node",
  21. "gcli/types/number",
  22. "gcli/types/resource",
  23. "gcli/types/setting",
  24. "gcli/types/string",
  25. "gcli/types/union",
  26. "gcli/types/url",
  27. "gcli/fields/fields",
  28. "gcli/fields/delegate",
  29. "gcli/fields/selection",
  30. "gcli/ui/focus",
  31. "gcli/ui/intro",
  32. "gcli/converters/converters",
  33. "gcli/converters/basic",
  34. "gcli/converters/terminal",
  35. "gcli/languages/command",
  36. "gcli/languages/javascript",
  37. "gcli/commands/clear",
  38. "gcli/commands/context",
  39. "gcli/commands/help",
  40. "gcli/commands/pref",
  41. ];
  42. /**
  43. * Some commands belong to a tool (see getToolModules). This is a list of the
  44. * modules that are *not* owned by a tool.
  45. */
  46. exports.devtoolsModules = [
  47. "devtools/shared/gcli/commands/addon",
  48. "devtools/shared/gcli/commands/appcache",
  49. "devtools/shared/gcli/commands/calllog",
  50. "devtools/shared/gcli/commands/cmd",
  51. "devtools/shared/gcli/commands/cookie",
  52. "devtools/shared/gcli/commands/csscoverage",
  53. "devtools/shared/gcli/commands/folder",
  54. "devtools/shared/gcli/commands/highlight",
  55. "devtools/shared/gcli/commands/inject",
  56. "devtools/shared/gcli/commands/jsb",
  57. "devtools/shared/gcli/commands/listen",
  58. "devtools/shared/gcli/commands/mdn",
  59. "devtools/shared/gcli/commands/measure",
  60. "devtools/shared/gcli/commands/media",
  61. "devtools/shared/gcli/commands/pagemod",
  62. "devtools/shared/gcli/commands/paintflashing",
  63. "devtools/shared/gcli/commands/qsa",
  64. "devtools/shared/gcli/commands/restart",
  65. "devtools/shared/gcli/commands/rulers",
  66. "devtools/shared/gcli/commands/screenshot",
  67. "devtools/shared/gcli/commands/security",
  68. ];
  69. /**
  70. * Register commands from tools with 'command: [ "some/module" ]' definitions.
  71. * The map/reduce incantation squashes the array of arrays to a single array.
  72. */
  73. try {
  74. const { defaultTools } = require("devtools/client/definitions");
  75. exports.devtoolsToolModules = defaultTools.map(def => def.commands || [])
  76. .reduce((prev, curr) => prev.concat(curr), []);
  77. } catch (e) {
  78. // "devtools/client/definitions" is only accessible from Firefox
  79. exports.devtoolsToolModules = [];
  80. }
  81. /**
  82. * Register commands from toolbox buttons with 'command: [ "some/module" ]'
  83. * definitions. The map/reduce incantation squashes the array of arrays to a
  84. * single array.
  85. */
  86. try {
  87. const { ToolboxButtons } = require("devtools/client/definitions");
  88. exports.devtoolsButtonModules = ToolboxButtons.map(def => def.commands || [])
  89. .reduce((prev, curr) => prev.concat(curr), []);
  90. } catch (e) {
  91. // "devtools/client/definitions" is only accessible from Firefox
  92. exports.devtoolsButtonModules = [];
  93. }
  94. /**
  95. * Add modules to a system for use in a content process (but don't call load)
  96. */
  97. exports.addAllItemsByModule = function(system) {
  98. system.addItemsByModule(exports.baseModules, { delayedLoad: true });
  99. system.addItemsByModule(exports.devtoolsModules, { delayedLoad: true });
  100. system.addItemsByModule(exports.devtoolsToolModules, { delayedLoad: true });
  101. system.addItemsByModule(exports.devtoolsButtonModules, { delayedLoad: true });
  102. const { mozDirLoader } = require("devtools/shared/gcli/commands/cmd");
  103. system.addItemsByModule("mozcmd", { delayedLoad: true, loader: mozDirLoader });
  104. };
  105. /**
  106. * This is WeakMap<Target, Links> where Links is an object that looks like
  107. * { refs: number, promise: Promise<System>, front: GcliFront }
  108. */
  109. var linksForTarget = new WeakMap();
  110. /**
  111. * The toolbox uses the following properties on a command to allow it to be
  112. * added to the toolbox toolbar
  113. */
  114. var customProperties = [ "buttonId", "buttonClass", "tooltipText" ];
  115. /**
  116. * Create a system which connects to a GCLI in a remote target
  117. * @return Promise<System> for the given target
  118. */
  119. exports.getSystem = function(target) {
  120. const existingLinks = linksForTarget.get(target);
  121. if (existingLinks != null) {
  122. existingLinks.refs++;
  123. return existingLinks.promise;
  124. }
  125. const system = createSystem({ location: "client" });
  126. exports.addAllItemsByModule(system);
  127. // Load the client system
  128. const links = {
  129. refs: 1,
  130. system,
  131. promise: system.load().then(() => {
  132. return GcliFront.create(target).then(front => {
  133. links.front = front;
  134. return connectFront(system, front, customProperties).then(() => system);
  135. });
  136. })
  137. };
  138. linksForTarget.set(target, links);
  139. return links.promise;
  140. };
  141. /**
  142. * Someone that called getSystem doesn't need it any more, so decrement the
  143. * count of users of the system for that target, and destroy if needed
  144. */
  145. exports.releaseSystem = function(target) {
  146. const links = linksForTarget.get(target);
  147. if (links == null) {
  148. throw new Error("releaseSystem called for unknown target");
  149. }
  150. links.refs--;
  151. if (links.refs === 0) {
  152. disconnectFront(links.system, links.front);
  153. links.system.destroy();
  154. linksForTarget.delete(target);
  155. }
  156. };