@@ -175,12 +175,12 @@ export class ConsolePinPane extends UI.Widget.VBox {
175175}
176176
177177export class ConsolePinPresenter {
178+ private readonly pin : ConsolePin ;
178179 private readonly pinElement : Element ;
179180 private readonly pinPreview : HTMLElement ;
180181 private lastResult : SDK . RuntimeModel . EvaluationResult | null ;
181182 private lastExecutionContext : SDK . RuntimeModel . ExecutionContext | null ;
182183 private editor : TextEditor . TextEditor . TextEditor ;
183- private committedExpression : string ;
184184 private hovered : boolean ;
185185 private lastNode : SDK . RemoteObject . RemoteObject | null ;
186186 private deletePinIcon : Buttons . Button . Button ;
@@ -219,11 +219,12 @@ export class ConsolePinPresenter {
219219
220220 this . lastResult = null ;
221221 this . lastExecutionContext = null ;
222- this . committedExpression = expression ;
223222 this . hovered = false ;
224223 this . lastNode = null ;
225224 this . editor = this . #createEditor( expression , nameElement ) ;
226225
226+ this . pin = new ConsolePin ( { workingCopy : ( ) => this . editor . state . doc . toString ( ) } , expression ) ;
227+
227228 this . pinPreview . addEventListener ( 'mouseenter' , this . setHovered . bind ( this , true ) , false ) ;
228229 this . pinPreview . addEventListener ( 'mouseleave' , this . setHovered . bind ( this , false ) , false ) ;
229230 this . pinPreview . addEventListener ( 'click' , ( event : Event ) => {
@@ -252,7 +253,7 @@ export class ConsolePinPresenter {
252253 {
253254 key : 'Escape' ,
254255 run : ( view : CodeMirror . EditorView ) => {
255- view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : this . committedExpression } } ) ;
256+ view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : this . pin . expression } } ) ;
256257 this . focusOut ( ) ;
257258 return true ;
258259 } ,
@@ -278,7 +279,7 @@ export class ConsolePinPresenter {
278279 return false ;
279280 }
280281 // User should be able to tab out of edit field after auto complete is done
281- view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : this . committedExpression } } ) ;
282+ view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : this . pin . expression } } ) ;
282283 this . focusOut ( ) ;
283284 return true ;
284285 } ,
@@ -290,7 +291,7 @@ export class ConsolePinPresenter {
290291 return false ;
291292 }
292293 // User should be able to tab out of edit field after auto complete is done
293- view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : this . committedExpression } } ) ;
294+ view . dispatch ( { changes : { from : 0 , to : view . state . doc . length , insert : this . pin . expression } } ) ;
294295 this . editor . blur ( ) ;
295296 this . deletePinIcon . focus ( ) ;
296297 return true ;
@@ -315,19 +316,18 @@ export class ConsolePinPresenter {
315316 }
316317
317318 #onBlur( editor : CodeMirror . EditorView ) : void {
318- const text = editor . state . doc . toString ( ) ;
319- const trimmedText = text . trim ( ) ;
320- this . committedExpression = trimmedText ;
319+ const commitedAsIs = this . pin . commit ( ) ;
321320 this . pinPane . savePins ( ) ;
322- if ( this . committedExpression . length ) {
323- UI . ARIAUtils . setLabel (
324- this . deletePinIcon , i18nString ( UIStrings . removeExpressionS , { PH1 : this . committedExpression } ) ) ;
321+ const newExpression = this . pin . expression ;
322+
323+ if ( newExpression . length ) {
324+ UI . ARIAUtils . setLabel ( this . deletePinIcon , i18nString ( UIStrings . removeExpressionS , { PH1 : newExpression } ) ) ;
325325 } else {
326326 UI . ARIAUtils . setLabel ( this . deletePinIcon , i18nString ( UIStrings . removeBlankExpression ) ) ;
327327 }
328328 editor . dispatch ( {
329- selection : { anchor : trimmedText . length } ,
330- changes : trimmedText !== text ? { from : 0 , to : text . length , insert : trimmedText } : undefined ,
329+ selection : { anchor : this . pin . expression . length } ,
330+ changes : ! commitedAsIs ? { from : 0 , to : this . editor . state . doc . length , insert : newExpression } : undefined ,
331331 } ) ;
332332 }
333333
@@ -342,7 +342,7 @@ export class ConsolePinPresenter {
342342 }
343343
344344 expression ( ) : string {
345- return this . committedExpression ;
345+ return this . pin . expression ;
346346 }
347347
348348 element ( ) : Element {
@@ -371,7 +371,7 @@ export class ConsolePinPresenter {
371371 }
372372 const text = TextEditor . Config . contentIncludingHint ( this . editor . editor ) ;
373373 const isEditing = this . pinElement . hasFocus ( ) ;
374- const throwOnSideEffect = isEditing && text !== this . committedExpression ;
374+ const throwOnSideEffect = isEditing && text !== this . pin . expression ;
375375 const timeout = throwOnSideEffect ? 250 : undefined ;
376376 const executionContext = UI . Context . Context . instance ( ) . flavor ( SDK . RuntimeModel . ExecutionContext ) ;
377377 const { preview, result} = await ObjectUI . JavaScriptREPL . JavaScriptREPL . evaluateAndBuildPreview (
@@ -416,3 +416,38 @@ export class ConsolePinPresenter {
416416 this . pinElement . classList . toggle ( 'error-level' , Boolean ( isError ) ) ;
417417 }
418418}
419+
420+ /**
421+ * Small helper interface to allow `ConsolePin` to retrieve the current working copy.
422+ */
423+ interface ConsolePinEditor {
424+ workingCopy ( ) : string ;
425+ }
426+
427+ /**
428+ * A pinned console expression.
429+ */
430+ export class ConsolePin {
431+ readonly #editor: ConsolePinEditor ;
432+ #expression: string ;
433+
434+ constructor ( editor : ConsolePinEditor , expression : string ) {
435+ this . #editor = editor ;
436+ this . #expression = expression ;
437+ }
438+
439+ get expression ( ) : string {
440+ return this . #expression;
441+ }
442+
443+ /**
444+ * Commit the current working copy from the editor.
445+ * @returns true, iff the working copy was commited as-is.
446+ */
447+ commit ( ) : boolean {
448+ const text = this . #editor. workingCopy ( ) ;
449+ const trimmedText = text . trim ( ) ;
450+ this . #expression = trimmedText ;
451+ return this . #expression === text ;
452+ }
453+ }
0 commit comments