index.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { Toolbar, ToolbarButton } from '@jupyterlab/apputils';
  4. import { Widget, Panel, PanelLayout } from '@phosphor/widgets';
  5. import { DebugProtocol } from 'vscode-debugprotocol';
  6. import { Body } from './body';
  7. import { Signal, ISignal } from '@phosphor/signaling';
  8. import { BreakpointsService } from '../breakpointsService';
  9. export class Breakpoints extends Panel {
  10. constructor(options: Breakpoints.IOptions) {
  11. super();
  12. this.service = options.service;
  13. if (this.service) {
  14. this.service.selectedBreakpointsChanged.connect((sender, update) => {
  15. this.model.breakpoints = update;
  16. });
  17. }
  18. this.model = new Breakpoints.IModel([]);
  19. this.addClass('jp-DebuggerBreakpoints');
  20. this.title.label = 'Breakpoints';
  21. const header = new BreakpointsHeader(this.title.label);
  22. this.body = new Body(this.model);
  23. this.addWidget(header);
  24. this.addWidget(this.body);
  25. header.toolbar.addItem(
  26. 'deactivate',
  27. new ToolbarButton({
  28. iconClassName: 'jp-DebuggerDeactivateIcon',
  29. tooltip: `${this.isAllActive ? 'Deactivate' : 'Activate'} Breakpoints`,
  30. onClick: () => {
  31. this.isAllActive = !this.isAllActive;
  32. this.model.breakpoints.map((breakpoint: Breakpoints.IBreakpoint) => {
  33. breakpoint.active = this.isAllActive;
  34. this.model.breakpoint = breakpoint;
  35. });
  36. }
  37. })
  38. );
  39. header.toolbar.addItem(
  40. 'closeAll',
  41. new ToolbarButton({
  42. iconClassName: 'jp-CloseAllIcon',
  43. onClick: () => {
  44. this.service.clearSelectedBreakpoints();
  45. },
  46. tooltip: 'Remove All Breakpoints'
  47. })
  48. );
  49. }
  50. private isAllActive = true;
  51. readonly body: Widget;
  52. readonly model: Breakpoints.IModel;
  53. service: BreakpointsService;
  54. }
  55. class BreakpointsHeader extends Widget {
  56. constructor(title: string) {
  57. super({ node: document.createElement('header') });
  58. const layout = new PanelLayout();
  59. const span = new Widget({ node: document.createElement('span') });
  60. this.layout = layout;
  61. span.node.textContent = title;
  62. layout.addWidget(span);
  63. layout.addWidget(this.toolbar);
  64. }
  65. readonly toolbar = new Toolbar();
  66. }
  67. export namespace Breakpoints {
  68. export interface IBreakpoint extends DebugProtocol.Breakpoint {
  69. active: boolean;
  70. }
  71. /**
  72. * The breakpoints UI model.
  73. */
  74. export interface IModel {}
  75. export class IModel implements IModel {
  76. constructor(model: IBreakpoint[]) {
  77. this._state = model;
  78. }
  79. get breakpointsChanged(): ISignal<this, IBreakpoint[]> {
  80. return this._breakpointsChanged;
  81. }
  82. get breakpoints(): IBreakpoint[] {
  83. return this._state;
  84. }
  85. get breakpointChanged(): ISignal<this, IBreakpoint> {
  86. return this._breakpointChanged;
  87. }
  88. set breakpoints(breakpoints: IBreakpoint[]) {
  89. this._state = breakpoints;
  90. this._breakpointsChanged.emit(breakpoints);
  91. }
  92. set breakpoint(breakpoint: IBreakpoint) {
  93. const index = this._state.findIndex(ele => ele.line === breakpoint.line);
  94. if (index !== -1) {
  95. this._state[index] = breakpoint;
  96. this._breakpointChanged.emit(breakpoint);
  97. } else {
  98. this.breakpoints = [...this.breakpoints, breakpoint];
  99. }
  100. }
  101. removeBreakpoint(breakpoint: IBreakpoint) {
  102. const breakpoints = this.breakpoints.filter(
  103. ele => ele.line !== breakpoint.line
  104. );
  105. this.breakpoints = breakpoints;
  106. }
  107. private _state: IBreakpoint[];
  108. private _breakpointsChanged = new Signal<this, IBreakpoint[]>(this);
  109. private _breakpointChanged = new Signal<this, IBreakpoint>(this);
  110. }
  111. /**
  112. * Instantiation options for `Breakpoints`;
  113. */
  114. export interface IOptions extends Panel.IOptions {
  115. service?: BreakpointsService;
  116. }
  117. }