Bug 1515736 - [release 111] re-add support chrome client (#7534). r=lsmyth
authorJason Laster <jlaster@mozilla.com>
Fri, 21 Dec 2018 11:49:14 -0500
changeset 451723 b82e0b0d6b6a941eb3bb5f45ff3af421f92f18ed
parent 451722 3774e75c5a76e8a805edc20e938fa337734ab65d
child 451724 026689094355e6a24849b4b650c124b39321d043
push id35252
push userccoroiu@mozilla.com
push dateFri, 21 Dec 2018 21:56:22 +0000
treeherdermozilla-central@b23630094b9c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsmyth
bugs1515736
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515736 - [release 111] re-add support chrome client (#7534). r=lsmyth
devtools/client/debugger/new/src/client/chrome.js
devtools/client/debugger/new/src/client/chrome/commands.js
devtools/client/debugger/new/src/client/chrome/create.js
devtools/client/debugger/new/src/client/chrome/events.js
devtools/client/debugger/new/src/client/chrome/moz.build
devtools/client/debugger/new/src/client/index.js
devtools/client/debugger/new/src/client/moz.build
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/src/client/chrome.js
@@ -0,0 +1,37 @@
+/* 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/>. */
+
+// @flow
+
+import { setupCommands, clientCommands } from "./chrome/commands";
+import { setupEvents, clientEvents, pageEvents } from "./chrome/events";
+
+export async function onConnect(connection: any, actions: Object): Object {
+  const {
+    tabConnection,
+    connTarget: { type }
+  } = connection;
+  const { Debugger, Runtime, Page } = tabConnection;
+
+  Debugger.enable();
+  Debugger.setPauseOnExceptions({ state: "none" });
+  Debugger.setAsyncCallStackDepth({ maxDepth: 0 });
+
+  if (type == "chrome") {
+    Page.frameNavigated(pageEvents.frameNavigated);
+    Page.frameStartedLoading(pageEvents.frameStartedLoading);
+    Page.frameStoppedLoading(pageEvents.frameStoppedLoading);
+  }
+
+  Debugger.scriptParsed(clientEvents.scriptParsed);
+  Debugger.scriptFailedToParse(clientEvents.scriptFailedToParse);
+  Debugger.paused(clientEvents.paused);
+  Debugger.resumed(clientEvents.resumed);
+
+  setupCommands({ Debugger, Runtime, Page });
+  setupEvents({ actions, Page, type, Runtime });
+  return {};
+}
+
+export { clientCommands, clientEvents };
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/src/client/chrome/commands.js
@@ -0,0 +1,144 @@
+/* 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/>. */
+
+// @flow
+
+import {
+  toServerLocation,
+  fromServerLocation,
+  createLoadedObject
+} from "./create";
+
+import type { SourceLocation } from "../../types";
+import type { ServerLocation, Agents } from "./types";
+
+type setBreakpointResponseType = {
+  breakpointId: string,
+  serverLocation?: ServerLocation
+};
+
+let debuggerAgent;
+let runtimeAgent;
+let pageAgent;
+
+function setupCommands({ Debugger, Runtime, Page }: Agents) {
+  debuggerAgent = Debugger;
+  runtimeAgent = Runtime;
+  pageAgent = Page;
+}
+
+function resume() {
+  return debuggerAgent.resume();
+}
+
+function stepIn() {
+  return debuggerAgent.stepInto();
+}
+
+function stepOver() {
+  return debuggerAgent.stepOver();
+}
+
+function stepOut() {
+  return debuggerAgent.stepOut();
+}
+
+function pauseOnExceptions(
+  shouldPauseOnExceptions: boolean,
+  shouldIgnoreCaughtExceptions: boolean
+) {
+  if (!shouldPauseOnExceptions) {
+    return debuggerAgent.setPauseOnExceptions({ state: "none" });
+  }
+  const state = shouldIgnoreCaughtExceptions ? "uncaught" : "all";
+  return debuggerAgent.setPauseOnExceptions({ state });
+}
+
+function breakOnNext() {
+  return debuggerAgent.pause();
+}
+
+function sourceContents(sourceId: string) {
+  return debuggerAgent
+    .getScriptSource({ scriptId: sourceId })
+    .then(({ scriptSource }) => ({
+      source: scriptSource,
+      contentType: null
+    }));
+}
+
+async function setBreakpoint(location: SourceLocation, condition: string) {
+  const {
+    breakpointId,
+    serverLocation
+  }: setBreakpointResponseType = await debuggerAgent.setBreakpoint({
+    location: toServerLocation(location),
+    columnNumber: location.column
+  });
+
+  const actualLocation = fromServerLocation(serverLocation) || location;
+
+  return {
+    id: breakpointId,
+    actualLocation: actualLocation
+  };
+}
+
+function removeBreakpoint(breakpointId: string) {
+  return debuggerAgent.removeBreakpoint({ breakpointId });
+}
+
+async function getProperties(object: any) {
+  const { result } = await runtimeAgent.getProperties({
+    objectId: object.objectId
+  });
+
+  const loadedObjects = result.map(createLoadedObject);
+
+  return { loadedObjects };
+}
+
+function evaluate(script: string) {
+  return runtimeAgent.evaluate({ expression: script });
+}
+
+function debuggeeCommand(script: string): Promise<void> {
+  evaluate(script);
+  return Promise.resolve();
+}
+
+function navigate(url: string) {
+  return pageAgent.navigate({ url });
+}
+
+function getBreakpointByLocation(location: SourceLocation) {}
+
+function setPausePoints() {}
+
+function getFrameScopes() {}
+function evaluateInFrame() {}
+function evaluateExpressions() {}
+
+const clientCommands = {
+  resume,
+  stepIn,
+  stepOut,
+  stepOver,
+  pauseOnExceptions,
+  breakOnNext,
+  sourceContents,
+  setBreakpoint,
+  removeBreakpoint,
+  evaluate,
+  debuggeeCommand,
+  navigate,
+  getProperties,
+  getBreakpointByLocation,
+  setPausePoints,
+  getFrameScopes,
+  evaluateInFrame,
+  evaluateExpressions
+};
+
+export { setupCommands, clientCommands };
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/src/client/chrome/create.js
@@ -0,0 +1,52 @@
+/* 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/>. */
+
+// @flow
+
+import type { SourceLocation, LoadedObject } from "../../types";
+import type { ServerLocation } from "./types";
+
+export function fromServerLocation(
+  serverLocation?: ServerLocation
+): ?SourceLocation {
+  if (serverLocation) {
+    return {
+      sourceId: serverLocation.scriptId,
+      line: serverLocation.lineNumber + 1,
+      column: serverLocation.columnNumber,
+      sourceUrl: ""
+    };
+  }
+}
+
+export function toServerLocation(location: SourceLocation): ServerLocation {
+  return {
+    scriptId: location.sourceId,
+    lineNumber: location.line - 1
+  };
+}
+
+export function createFrame(frame: any) {
+  return {
+    id: frame.callFrameId,
+    displayName: frame.functionName,
+    scopeChain: frame.scopeChain,
+    generatedLocation: frame.location,
+    location: fromServerLocation(frame.location)
+  };
+}
+
+export function createLoadedObject(
+  serverObject: any,
+  parentId: string
+): LoadedObject {
+  const { value, name } = serverObject;
+
+  return {
+    objectId: value.objectId,
+    parentId,
+    name,
+    value
+  };
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/src/client/chrome/events.js
@@ -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/>. */
+
+// @flow
+
+import { createFrame, createLoadedObject } from "./create";
+
+let actions;
+let pageAgent;
+let clientType;
+let runtimeAgent;
+
+function setupEvents(dependencies: any) {
+  actions = dependencies.actions;
+  pageAgent = dependencies.Page;
+  clientType = dependencies.clientType;
+  runtimeAgent = dependencies.Runtime;
+}
+
+// Debugger Events
+function scriptParsed({
+  scriptId,
+  url,
+  startLine,
+  startColumn,
+  endLine,
+  endColumn,
+  executionContextId,
+  hash,
+  isContentScript,
+  isInternalScript,
+  isLiveEdit,
+  sourceMapURL,
+  hasSourceURL,
+  deprecatedCommentWasUsed
+}: any) {
+  if (isContentScript) {
+    return;
+  }
+
+  if (clientType == "node") {
+    sourceMapURL = undefined;
+  }
+
+  actions.newSource({
+    id: scriptId,
+    url,
+    sourceMapURL,
+    isPrettyPrinted: false
+  });
+}
+
+function scriptFailedToParse() {}
+
+async function paused({
+  callFrames,
+  reason,
+  data,
+  hitBreakpoints,
+  asyncStackTrace
+}: any) {
+  const frames = callFrames.map(createFrame);
+  const frame = frames[0];
+  const why = { type: reason, ...data };
+
+  const objectId = frame.scopeChain[0].object.objectId;
+  const { result } = await runtimeAgent.getProperties({
+    objectId
+  });
+
+  const loadedObjects = result.map(createLoadedObject);
+
+  if (clientType == "chrome") {
+    pageAgent.configureOverlay({ message: "Paused in debugger.html" });
+  }
+
+  await actions.paused({ frame, why, frames, loadedObjects });
+}
+
+function resumed() {
+  if (clientType == "chrome") {
+    pageAgent.configureOverlay({ suspended: false });
+  }
+
+  actions.resumed();
+}
+
+function globalObjectCleared() {}
+
+// Page Events
+function frameNavigated(frame: any) {
+  actions.navigated();
+}
+
+function frameStartedLoading() {
+  actions.willNavigate();
+}
+
+function domContentEventFired() {}
+
+function loadEventFired() {}
+
+function frameStoppedLoading() {}
+
+const clientEvents = {
+  scriptParsed,
+  scriptFailedToParse,
+  paused,
+  resumed,
+  globalObjectCleared
+};
+
+const pageEvents = {
+  frameNavigated,
+  frameStartedLoading,
+  domContentEventFired,
+  loadEventFired,
+  frameStoppedLoading
+};
+
+export { setupEvents, pageEvents, clientEvents };
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/src/client/chrome/moz.build
@@ -0,0 +1,14 @@
+# vim: set filetype=python:
+# 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/.
+
+DIRS += [
+
+]
+
+DebuggerModules(
+    'commands.js',
+    'create.js',
+    'events.js',
+)
--- a/devtools/client/debugger/new/src/client/index.js
+++ b/devtools/client/debugger/new/src/client/index.js
@@ -1,15 +1,16 @@
 /* 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/>. */
 
 // @flow
 
 import * as firefox from "./firefox";
+import * as chrome from "./chrome";
 
 import { prefs, asyncStore } from "../utils/prefs";
 import { setupHelper } from "../utils/dbg";
 
 import {
   bootstrapApp,
   bootstrapStore,
   bootstrapWorkers
@@ -41,44 +42,55 @@ async function loadInitialState() {
   const tabs = await asyncStore.tabs;
   const xhrBreakpoints = await asyncStore.xhrBreakpoints;
 
   const breakpoints = initialBreakpointsState(xhrBreakpoints);
 
   return { pendingBreakpoints, tabs, breakpoints };
 }
 
+function getClient(connection: any) {
+  const {
+    tab: { clientType }
+  } = connection;
+  return clientType == "firefox" ? firefox : chrome;
+}
+
 export async function onConnect(
   connection: Object,
   { services, toolboxActions }: Object
 ) {
   // NOTE: the landing page does not connect to a JS process
   if (!connection) {
     return;
   }
 
-  const commands = firefox.clientCommands;
+  const client = getClient(connection);
+  const commands = client.clientCommands;
+
   const initialState = await loadInitialState();
+
   const { store, actions, selectors } = bootstrapStore(
     commands,
     {
       services,
       toolboxActions
     },
     initialState
   );
 
   const workers = bootstrapWorkers();
-  await firefox.onConnect(connection, actions);
+  await client.onConnect(connection, actions);
+
   await loadFromPrefs(actions);
   syncXHRBreakpoints();
   setupHelper({
     store,
     actions,
     selectors,
     workers: { ...workers, ...services },
     connection,
-    client: firefox.clientCommands
+    client: client.clientCommands
   });
 
   bootstrapApp(store);
   return { store, actions, selectors, client: commands };
 }
--- a/devtools/client/debugger/new/src/client/moz.build
+++ b/devtools/client/debugger/new/src/client/moz.build
@@ -1,13 +1,15 @@
 # vim: set filetype=python:
 # 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/.
 
 DIRS += [
+    'chrome',
     'firefox',
 ]
 
 DebuggerModules(
+    'chrome.js',
     'firefox.js',
     'index.js',
 )