crDevTools.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.CRDevTools = void 0;
  6. var _fs = _interopRequireDefault(require("fs"));
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. /**
  9. * Copyright (c) Microsoft Corporation.
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. const kBindingName = '__pw_devtools__';
  24. // This class intercepts preferences-related DevTools embedder methods
  25. // and stores preferences as a json file in the browser installation directory.
  26. class CRDevTools {
  27. constructor(preferencesPath) {
  28. this._preferencesPath = void 0;
  29. this._prefs = void 0;
  30. this._savePromise = void 0;
  31. this.__testHookOnBinding = void 0;
  32. this._preferencesPath = preferencesPath;
  33. this._savePromise = Promise.resolve();
  34. }
  35. install(session) {
  36. session.on('Runtime.bindingCalled', async event => {
  37. if (event.name !== kBindingName) return;
  38. const parsed = JSON.parse(event.payload);
  39. let result = undefined;
  40. if (this.__testHookOnBinding) this.__testHookOnBinding(parsed);
  41. if (parsed.method === 'getPreferences') {
  42. if (this._prefs === undefined) {
  43. try {
  44. const json = await _fs.default.promises.readFile(this._preferencesPath, 'utf8');
  45. this._prefs = JSON.parse(json);
  46. } catch (e) {
  47. this._prefs = {};
  48. }
  49. }
  50. result = this._prefs;
  51. } else if (parsed.method === 'setPreference') {
  52. this._prefs[parsed.params[0]] = parsed.params[1];
  53. this._save();
  54. } else if (parsed.method === 'removePreference') {
  55. delete this._prefs[parsed.params[0]];
  56. this._save();
  57. } else if (parsed.method === 'clearPreferences') {
  58. this._prefs = {};
  59. this._save();
  60. }
  61. session.send('Runtime.evaluate', {
  62. expression: `window.DevToolsAPI.embedderMessageAck(${parsed.id}, ${JSON.stringify(result)})`,
  63. contextId: event.executionContextId
  64. }).catch(e => null);
  65. });
  66. Promise.all([session.send('Runtime.enable'), session.send('Runtime.addBinding', {
  67. name: kBindingName
  68. }), session.send('Page.enable'), session.send('Page.addScriptToEvaluateOnNewDocument', {
  69. source: `
  70. (() => {
  71. const init = () => {
  72. // Lazy init happens when InspectorFrontendHost is initialized.
  73. // At this point DevToolsHost is ready to be used.
  74. const host = window.DevToolsHost;
  75. const old = host.sendMessageToEmbedder.bind(host);
  76. host.sendMessageToEmbedder = message => {
  77. if (['getPreferences', 'setPreference', 'removePreference', 'clearPreferences'].includes(JSON.parse(message).method))
  78. window.${kBindingName}(message);
  79. else
  80. old(message);
  81. };
  82. };
  83. let value;
  84. Object.defineProperty(window, 'InspectorFrontendHost', {
  85. configurable: true,
  86. enumerable: true,
  87. get() { return value; },
  88. set(v) { value = v; init(); },
  89. });
  90. })()
  91. `
  92. }), session.send('Runtime.runIfWaitingForDebugger')]).catch(e => null);
  93. }
  94. _save() {
  95. // Serialize saves to avoid corruption.
  96. this._savePromise = this._savePromise.then(async () => {
  97. await _fs.default.promises.writeFile(this._preferencesPath, JSON.stringify(this._prefs)).catch(e => null);
  98. });
  99. }
  100. }
  101. exports.CRDevTools = CRDevTools;