Bug 1517349 - [release 115] [breakpoints] log points updates (#7632). r=dwalsh
authorJason Laster <jlaster@mozilla.com>
Wed, 02 Jan 2019 16:59:35 -0500
changeset 509434 b2e2a91389d1908f5bba913cd91e6a7b68c3963d
parent 509433 0340904ea2bc20c873c977d2f93e5124bd4dedef
child 509435 398f606ed20d75b39910dfb0847eb192bbf96538
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdwalsh
bugs1517349
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 1517349 - [release 115] [breakpoints] log points updates (#7632). r=dwalsh
devtools/client/debugger/new/dist/debugger.css
devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
devtools/client/debugger/new/src/actions/breakpoints/index.js
devtools/client/debugger/new/src/components/Editor/Breakpoint.js
devtools/client/debugger/new/src/components/Editor/ConditionalPanel.js
devtools/client/debugger/new/src/components/Editor/GutterMenu.js
devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
devtools/client/debugger/new/src/selectors/breakpointSources.js
devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
devtools/client/debugger/new/src/utils/breakpoint/index.js
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -2758,16 +2758,21 @@ menuseparator {
   fill-opacity: 0.5;
 }
 
 .column-breakpoint.has-condition svg {
   fill: var(--theme-graphs-yellow);
   stroke: var(--theme-graphs-orange);
 }
 
+.column-breakpoint.has-condition.log svg {
+  fill: var(--theme-graphs-orange);
+  stroke: var(--theme-graphs-yellow);
+}
+
 .theme-dark .column-breakpoint.active svg {
   fill: var(--blue-55);
   stroke: var(--blue-40);
 }
 
 .theme-dark .column-breakpoint.disabled svg {
   fill: var(--blue-50);
   stroke: var(--blue-60);
@@ -2967,16 +2972,21 @@ html[dir="rtl"] .editor-mount {
   right: -16px;
 }
 
 .new-breakpoint.has-condition .CodeMirror-gutter-wrapper svg {
   fill: var(--theme-graphs-yellow);
   stroke: var(--theme-graphs-orange);
 }
 
+.new-breakpoint.has-condition.log .CodeMirror-gutter-wrapper svg {
+  fill: var(--theme-graphs-orange);
+  stroke: var(--theme-graphs-yellow);
+}
+
 .editor.new-breakpoint.breakpoint-disabled svg {
   fill: var(--breakpoint-fill-disabled);
   stroke: var(--breakpoint-stroke-disabled);
   fill-opacity: 0.5;
 }
 
 .editor.column-breakpoint svg {
   fill: var(--theme-selection-background);
@@ -3242,16 +3252,24 @@ html:not([dir="rtl"]) .breakpoints-excep
 html:not([dir="rtl"]) .breakpoints-list .breakpoint.is-conditional {
   border-left-color: var(--theme-graphs-yellow);
 }
 
 html[dir="rtl"] .breakpoints-list .breakpoint.is-conditional {
   border-right-color: var(--theme-graphs-yellow);
 }
 
+html:not([dir="rtl"]) .breakpoints-list .breakpoint.is-conditional.log {
+  border-left-color: var(--theme-graphs-orange);
+}
+
+html[dir="rtl"] .breakpoints-list .breakpoint.is-conditional.log {
+  border-right-color: var(--theme-graphs-orange);
+}
+
 html .breakpoints-list .breakpoint.paused {
   background-color: var(--theme-toolbar-background-alt);
   border-color: var(--breakpoint-active-color);
 }
 
 .breakpoints-list .breakpoint.disabled .breakpoint-label {
   color: var(--theme-comment);
   transition: color 0.15s linear;
--- a/devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
@@ -73,16 +73,17 @@ async function addBreakpointPromise(getS
   const text = getTextAtPosition(generatedSource, actualLocation);
 
   const newBreakpoint = {
     id,
     disabled: false,
     hidden: breakpoint.hidden,
     loading: false,
     condition: breakpoint.condition,
+    log: breakpoint.log,
     location: newLocation,
     astLocation,
     generatedLocation: newGeneratedLocation,
     text,
     originalText
   };
 
   assertBreakpoint(newBreakpoint);
@@ -145,21 +146,22 @@ export function enableBreakpoint(locatio
  * @memberof actions/breakpoints
  * @static
  * @param {String} $1.condition Conditional breakpoint condition value
  * @param {Boolean} $1.disabled Disable value for breakpoint value
  */
 
 export function addBreakpoint(
   location: SourceLocation,
-  { condition, hidden }: addBreakpointOptions = {}
+  { condition, hidden, log = false }: addBreakpointOptions = {}
 ) {
-  const breakpoint = createBreakpoint(location, { condition, hidden });
   return ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
     recordEvent("add_breakpoint");
 
+    const breakpoint = createBreakpoint(location, { condition, hidden, log });
+
     return dispatch({
       type: "ADD_BREAKPOINT",
       breakpoint,
       [PROMISE]: addBreakpointPromise(getState, client, sourceMaps, breakpoint)
     });
   };
 }
--- a/devtools/client/debugger/new/src/actions/breakpoints/index.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/index.js
@@ -39,17 +39,18 @@ import type {
   SourceLocation,
   XHRBreakpoint
 } from "../../types";
 
 import { recordEvent } from "../../utils/telemetry";
 
 export type addBreakpointOptions = {
   condition?: string,
-  hidden?: boolean
+  hidden?: boolean,
+  log?: boolean
 };
 
 /**
  * Remove a single breakpoint
  *
  * @memberof actions/breakpoints
  * @static
  */
@@ -191,21 +192,20 @@ export function toggleAllBreakpoints(sho
  * @memberof actions/breakpoints
  * @static
  */
 export function toggleBreakpoints(
   shouldDisableBreakpoints: boolean,
   breakpoints: Breakpoint[]
 ) {
   return async ({ dispatch }: ThunkArgs) => {
-    const promises = breakpoints.map(
-      breakpoint =>
-        shouldDisableBreakpoints
-          ? dispatch(disableBreakpoint(breakpoint.location))
-          : dispatch(enableBreakpoint(breakpoint.location))
+    const promises = breakpoints.map(breakpoint =>
+      shouldDisableBreakpoints
+        ? dispatch(disableBreakpoint(breakpoint.location))
+        : dispatch(enableBreakpoint(breakpoint.location))
     );
 
     await Promise.all(promises);
   };
 }
 
 /**
  * Removes all breakpoints
@@ -278,22 +278,22 @@ export function remapBreakpoints(sourceI
  * @param {SourceLocation} location
  *        @see DebuggerController.Breakpoints.addBreakpoint
  * @param {string} condition
  *        The condition to set on the breakpoint
  * @param {Boolean} $1.disabled Disable value for breakpoint value
  */
 export function setBreakpointCondition(
   location: SourceLocation,
-  { condition }: addBreakpointOptions = {}
+  { condition, log = false }: addBreakpointOptions = {}
 ) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
     const bp = getBreakpoint(getState(), location);
     if (!bp) {
-      return dispatch(addBreakpoint(location, { condition }));
+      return dispatch(addBreakpoint(location, { condition, log }));
     }
 
     if (bp.loading) {
       return;
     }
 
     if (bp.disabled) {
       await dispatch(enableBreakpoint(location));
@@ -301,17 +301,17 @@ export function setBreakpointCondition(
 
     await client.setBreakpointCondition(
       bp.id,
       location,
       condition,
       isOriginalId(bp.location.sourceId)
     );
 
-    const newBreakpoint = { ...bp, disabled: false, condition };
+    const newBreakpoint = { ...bp, disabled: false, condition, log };
 
     assertBreakpoint(newBreakpoint);
 
     return dispatch(
       ({
         type: "SET_BREAKPOINT_CONDITION",
         breakpoint: newBreakpoint
       }: Action)
--- a/devtools/client/debugger/new/src/components/Editor/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/Editor/Breakpoint.js
@@ -56,17 +56,21 @@ class Breakpoint extends PureComponent<P
     editor.codeMirror.setGutterMarker(
       line,
       "breakpoints",
       makeMarker(breakpoint.disabled)
     );
 
     editor.codeMirror.addLineClass(line, "line", "new-breakpoint");
     if (breakpoint.condition) {
-      editor.codeMirror.addLineClass(line, "line", "has-condition");
+      if (breakpoint.log) {
+        editor.codeMirror.addLineClass(line, "line", "has-condition log");
+      } else {
+        editor.codeMirror.addLineClass(line, "line", "has-condition");
+      }
     } else {
       editor.codeMirror.removeLineClass(line, "line", "has-condition");
     }
   };
 
   componentDidMount() {
     this.addBreakpoint();
   }
--- a/devtools/client/debugger/new/src/components/Editor/ConditionalPanel.js
+++ b/devtools/client/debugger/new/src/components/Editor/ConditionalPanel.js
@@ -62,17 +62,17 @@ export class ConditionalPanel extends Pu
     }
   };
 
   setBreakpoint(condition: string) {
     const { location, log } = this.props;
     if (log) {
       condition = `console.log(${condition})`;
     }
-    return this.props.setBreakpointCondition(location, { condition });
+    return this.props.setBreakpointCondition(location, { condition, log });
   }
 
   clearConditionalPanel() {
     if (this.cbPanel) {
       this.cbPanel.clear();
       this.cbPanel = null;
     }
     if (this.scrollParent) {
--- a/devtools/client/debugger/new/src/components/Editor/GutterMenu.js
+++ b/devtools/client/debugger/new/src/components/Editor/GutterMenu.js
@@ -115,17 +115,22 @@ export function gutterMenu({
         breakpoint ? breakpoint.location : { line, column, sourceId }
       ),
     accelerator: L10N.getStr("toggleCondPanel.key"),
     ...(breakpoint && breakpoint.condition
       ? gutterItems.editConditional
       : gutterItems.addConditional)
   };
 
-  const items = [toggleBreakpointItem, conditionalBreakpoint, logPoint];
+  let items = [toggleBreakpointItem, conditionalBreakpoint, logPoint];
+
+  if (breakpoint && breakpoint.condition) {
+    const remove = breakpoint.log ? conditionalBreakpoint : logPoint;
+    items = items.filter(item => item !== remove);
+  }
 
   if (isPaused) {
     const continueToHereItem = {
       accesskey: L10N.getStr("editor.continueToHere.accesskey"),
       disabled: false,
       click: () => continueToHere(line, column),
       ...gutterItems.continueToHere
     };
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
@@ -130,24 +130,24 @@ class Breakpoint extends PureComponent<P
     const node = document.createElement("div");
     editor.CodeMirror.runMode(text, "application/javascript", node);
     return { __html: node.innerHTML };
   }
 
   /* eslint-disable react/no-danger */
   render() {
     const { breakpoint } = this.props;
-
     return (
       <div
         className={classnames({
           breakpoint,
           paused: this.isCurrentlyPausedAtBreakpoint(),
           disabled: breakpoint.disabled,
-          "is-conditional": !!breakpoint.condition
+          "is-conditional": !!breakpoint.condition,
+          log: breakpoint.log
         })}
         onClick={this.selectBreakpoint}
         onDoubleClick={this.onDoubleClick}
         onContextMenu={this.onContextMenu}
       >
         <input
           type="checkbox"
           className="breakpoint-checkbox"
--- a/devtools/client/debugger/new/src/selectors/breakpointSources.js
+++ b/devtools/client/debugger/new/src/selectors/breakpointSources.js
@@ -34,22 +34,23 @@ export type FormattedBreakpoint = {|
   text: string,
   selectedLocation: SourceLocation
 |};
 
 function formatBreakpoint(
   breakpoint: Breakpoint,
   selectedSource: ?Source
 ): FormattedBreakpoint {
-  const { id, condition, disabled } = breakpoint;
+  const { id, condition, disabled, log } = breakpoint;
 
   return {
     id,
     condition,
     disabled,
+    log,
     text:
       selectedSource && isGenerated(selectedSource)
         ? breakpoint.text
         : breakpoint.originalText,
     selectedLocation: getSelectedLocation(breakpoint, selectedSource)
   };
 }
 
--- a/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleBreakpoints.js
@@ -19,26 +19,27 @@ import type { Selector } from "../reduce
 
 function getLocation(breakpoint, isGeneratedSource) {
   return isGeneratedSource
     ? breakpoint.generatedLocation || breakpoint.location
     : breakpoint.location;
 }
 
 const formatBreakpoint = memoize(function(breakpoint, selectedSource) {
-  const { condition, loading, disabled, hidden } = breakpoint;
+  const { condition, loading, disabled, hidden, log } = breakpoint;
   const sourceId = selectedSource.id;
   const isGeneratedSource = isGeneratedId(sourceId);
 
   return {
     location: getLocation(breakpoint, isGeneratedSource),
     condition,
     loading,
     disabled,
-    hidden
+    hidden,
+    log
   };
 });
 
 function isVisible(breakpoint: Breakpoint, selectedSource: Source) {
   const sourceId = selectedSource.id;
   const isGeneratedSource = isGeneratedId(sourceId);
 
   const location = getLocation(breakpoint, isGeneratedSource);
@@ -66,15 +67,18 @@ export const getVisibleBreakpoints: Sele
   }
 );
 
 /*
  * Finds the first breakpoint per line, which appear in the selected source.
  */
 export const getFirstVisibleBreakpoints: Selector<
   Breakpoint[]
-> = createSelector(getVisibleBreakpoints, breakpoints => {
-  if (!breakpoints) {
-    return [];
+> = createSelector(
+  getVisibleBreakpoints,
+  breakpoints => {
+    if (!breakpoints) {
+      return [];
+    }
+
+    return (uniqBy(sortBreakpoints(breakpoints), bp => bp.location.line): any);
   }
-
-  return (uniqBy(sortBreakpoints(breakpoints), bp => bp.location.line): any);
-});
+);
--- a/devtools/client/debugger/new/src/utils/breakpoint/index.js
+++ b/devtools/client/debugger/new/src/utils/breakpoint/index.js
@@ -125,27 +125,29 @@ export function createBreakpoint(
   const {
     condition,
     disabled,
     hidden,
     generatedLocation,
     astLocation,
     id,
     text,
-    originalText
+    originalText,
+    log
   } = overrides;
 
   const defaultASTLocation = {
     name: undefined,
     offset: location,
     index: 0
   };
   const properties = {
     id,
     condition: condition || null,
+    log: log || false,
     disabled: disabled || false,
     hidden: hidden || false,
     loading: false,
     astLocation: astLocation || defaultASTLocation,
     generatedLocation: generatedLocation || location,
     location,
     text,
     originalText
@@ -178,16 +180,17 @@ function createPendingLocation(location:
 export function createPendingBreakpoint(bp: Breakpoint) {
   const pendingLocation = createPendingLocation(bp.location);
   const pendingGeneratedLocation = createPendingLocation(bp.generatedLocation);
 
   assertPendingLocation(pendingLocation);
 
   return {
     condition: bp.condition,
+    log: bp.log,
     disabled: bp.disabled,
     location: pendingLocation,
     astLocation: bp.astLocation,
     generatedLocation: pendingGeneratedLocation
   };
 }
 
 export function sortFormattedBreakpoints(breakpoints: FormattedBreakpoint[]) {